SpringBoot中Bean按条件装配

@Conditional条件装配
  • @Conditional是Spring Framework提供的一个核心功能注解,这个注解的作用是提供自动装配的条件限制,一般我们在用@Configuration,@Bean的时候使用它。
  • 也就是我们在自定义Bean的注入的时候,我们可以通过@Condition来对bean的注入增加逻辑判断,符合我们要求的我们才让他自动装配
@Conditional 的使用
  • 如下注解源码是@Condition
@FunctionalInterface
public interface Condition {

	/**
	 * Determine if the condition matches.
	 * @param context the condition context
	 * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
	 * or {@link org.springframework.core.type.MethodMetadata method} being checked
	 * @return {@code true} if the condition matches and the component can be registered,
	 * or {@code false} to veto the annotated component's registration
	 */
	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

}
  • condition是一个函数式接口,提供了一个matches方法,主要提供一个条件匹配的规则,返回表示是否可以注入Bean。

  • @Conditional 的注解来声明如下,他可以接受接收一个Condition的数组

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {

	/**
	 * All {@link Condition Conditions} that must {@linkplain Condition#matches match}
	 * in order for the component to be registered.
	 */
	Class<? extends Condition>[] value();

}
Conditional使用Demo
  • 我们通过对以上Conditional的了解来自己实现一个Bean的按自定义条件的装配:
  • 定义一个Condition,判断系统来返回是否装配:
/**
 * Created by jiamin5 on 2022/3/10.
 */
public class GpCondition implements Condition{
    private static final Logger logger = LoggerFactory.getLogger(GpCondition.class);

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String os = context.getEnvironment().getProperty("os.name");
        logger.info("GpCondition matthes osName:{}", os);
        if(os.contains("Windows")){
            return true;
        }
        return false;
    }
}
  • 定义配置类,装载一个BeanTestClass
/**
 * Created by jiamin5 on 2022/3/10.
 */
@Configuration
public class ConditionConfig {

    @Bean
    @Conditional(GpCondition.class)
    public BeanTestClass beanTestClass(){
        return new BeanTestClass();
    }
}
  • 如上,我们在BeanTestClass上增加了一个@Conditional(GpCondition.class),其中的具体条件就是我们自定义的注入限制条件类。
  • 意思就是,当条件满足我们定义的GpCondition的时候,我们就注入,否则不注入。
  • 依然在Application启动类中添加对新定义Bean的获取,如下
/**
 * @author liaojiamin
 * @Date:Created in 11:08 2022/3/7
 */
@SpringBootApplication
@EnableAutoImport
public class Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext ca = SpringApplication.run(Application.class, args);
        System.out.println(ca.getBean(FilterFirstObj.class));
        BeanTestClass beanTestClass = ca.getBean(BeanTestClass.class);
        System.out.println(beanTestClass);
    }
}

  • 当我们在Mac os上运行,有如下结果

在这里插入图片描述

Spring Boot 中的@Conditional
  • 在SpringBoot中,有针对@Conditional的扩展,提供了更简单的使用方式,扩张了各种类型的注解,如下:

    • ConditionalOnBean/ConditionalOnMissBean 容器中存在或者不存在某个类的时候进行Bean加载
    • ConditionalOnClass/ConditionalOnMissClass:classpath下存在或者不存在指定类的时候进行Bean加载
    • ConditionalOnCloudPlatform:只允许在指定的云平台上才加载指定Bean
    • ConditionalOnExpression:基于SpEl表达式的条件判断
    • ConditionalOnJava:只允许在指定版本Java才加载Bean
    • ConditionalOnJndi:只有指定资源通过JNDI加载后才加载Bean
    • ConditionalOnWebApplication/ConsitionalOnNotWebApplication:如果是活着不是web应用才加载指定的Bean
    • ConditionalOnProperty:系统中指定对呀的属性是否有对应值
    • ConditionOnResource:要加载的Bean依赖指定资源是否存在于classpath
    • ConditionOnSingleCandidate:只有在确定了给定Bean的单个候选项时候才会加载Bean
  • 以上这些都在spring-boot-autoconfiguration.jar 中
    在这里插入图片描述

其他注入方式spring-autoconfigure-metadata
  • 除了@Conditional注解。Spring Boot中提供了spring-autoconfigure-metadata.properties文件来实现批量自动装配条件配置

  • 与@Conditional意义,只是将条件放在的文件,我们可以在spring-boot-autoconfigure.jar中找到这种配置
    在这里插入图片描述

  • 同样遵循“约定由于配置”,通过这种配置实现条件过滤需保证两个前提条件:

    • 如上图中,文件路径名称必须是/META-INF/spring-autoconfigure-metadata.properties
    • 配置文件的key’的配置格式:自动配置类的类全路径名.条件 = 值
  • 这种配置优点在于可以有效降低Spring Boot启动时间,通过这种过滤方式减少配置陪的加载数量,因为这个过滤发生在配置类的装载之前,所以他可以降低Spring Boot启动时装载Bean的耗时

上一篇:SpringBoot自动装配源码解析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值