Springboot学习笔记(五)-条件化注入

前言

将Bean交给spring托管很简单,根据功能在类上添加@Component,@Service,@Controller等等都行,如果是第三方类,也可以通过标有@Configuration的配置类来进行注入。但并不是所有被注入的bean都用得着,无脑注入会浪费资源。springboot提供了条件化配置,只有在满足注入条件才实例化。比如自定义一个ServiceHelloService,希望在spring.profiles.active=local时才加载。

基础

springboot中提供了Condition接口,实现它即可定义自己的条件:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Arrays;

public class HelloCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return Arrays.stream(context.getEnvironment().getActiveProfiles())
                .anyMatch("local"::equals);
    }
}

HelloService:

import com.yan.springboot.condition.HelloCondition;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;

@Component
@Conditional(HelloCondition.class)
public class HelloService {
    public void sayHi() {
        LoggerFactory.getLogger(HelloService.class).info("Hello World!");
    }
}

测试:

import com.yan.springboot.service.HelloService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
    @Autowired(required = false)
    private HelloService helloService;

    @Test
    public void test() {
        Assert.assertTrue(null == helloService);
    }
}

测试通过。
此时在配置文件中加入spring.profiles.active=local则会报错(断言错误,helloService存在),可见它已生效。

扩展

Springboot中提供了很多条件化配置的注解,只要输入@ConditionalOn就能出现一大堆:

不过比较常用的也就几种:

/*******************
 *   Class包含Bean *
 ******************/

// 容器中有ThreadPoolTaskExecutor类型的bean时才注入
@ConditionalOnBean(ThreadPoolTaskExecutor.class)
@ConditionalOnMissingBean(ThreadPoolTaskExecutor.class)
// 类路径中有ThreadPoolTaskExecutor类型的bean时才注入
@ConditionalOnClass(ThreadPoolTaskExecutor.class)
@ConditionalOnMissingClass

// 在配置文件中查找hello.name的值,如果能找到并且值等于yan,就注入,如果根本就没配,也注入,这就是matchIfMissing = true的含义
@ConditionalOnProperty(prefix = "hello", name = "name", havingValue = "yan", matchIfMissing = true)

//只在web环境下注入
@ConditionalOnWebApplication

// java8或以上环境才注入
@ConditionalOnJava(ConditionalOnJava.JavaVersion.EIGHT)
posted @   舒山  阅读(7874)  评论(1编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示