SpringBoot学习(三):基于@Conditional条件化加载的自动配置

一、概述

  • 在基于springboot的项目当中,通过在应用主类中添加@SpringBootApplication或者@EnableAutoConfiguration注解,可以激活SpringBoot的自动配置机制,为应用提供一系列默认的功能组件,在应用中可以直接使用如@Autowired注解注入即可,而不需要在应用中显式配置。
  • 在SpringBoot内部实现中,每个自动配置的功能组件都对应一个使用@Configuration注解的配置类,Spring容器在启动处理@EnableAutoConfiguration注解时,会自动加载这些配置类;然后基于@Contional注解提供的条件化加载机制,决定是否将在该配置类内部通过@Bean注解定义的功能组件加载到Spring容器。

二、@Conditional注解体系结构

  • @Conditional是在Spring4.0引入的,主要用在需要条件化加载的类或方法上,即只有@Conditional注解中指定条件均满足时,才加载该类或方法对应的bean到Spring容器,其中条件化为基于Spring4.0提供的Condition接口实现类来实现。
  • @Conditional注解的定义如下:在value中指定一个或多个需要满足的条件,即Conditon接口的实现类。

  • Condition接口的定义如下:每个Condition接口实现类表示某个特定的条件,实现matches方法,基于当前类的注解元数据metadata来定义该特定条件的判断逻辑(或方法的注解元数据,以下类似,不再赘述)。

1.作用域

  • 类级别:与@Component及其子注解,@Configuration注解一起使用,基于@Conditonal注解指定的条件,判断是否需要加载该类到Spring容器;
  • 注解级别:附加到其他注解定义中,构成复合注解。@SpringBootApplication就是一个复合注解,包含@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan三个注解。
  • 方法级别:与@Bean注解一起使用,判断是否需要加载方法对应的bean到Spring容器。

2.与其他注解的关系

  • 与@Configuration注解一起使用:当@Conditional注解指定条件无法满足时,则该配置类上的其他注解都不会生效,包括@ComponentScan,@Import,@PropertySource等,以及也不会注册配置类内部的@Bean注解的方法对应的bean到Spring容器。所以在类级别进行控制。
  • 与@Bean注解一起使用:当@Conditional注解指定的条件无法满足时,则@Bean注解的方法对应的bean不会注册到Spring容器。所以在方法级别进行更加细粒度的控制。

3.案例分析:RedisAutoConfiguration

  • 以RedisAutoConfiguration这个SpringBoot针对Redis提供的配置类为例,RedisAutoConfiguration配置类定义如下:

  • 与@Configuration一起使用: @ConditionalOnClass(RedisOperations.class): 当类路径下存在RedisOperations的实现类,即应用中存在存在Redis相关操作时,激活该配置类;
  • 与@Bean一起使用:在redisTemplate方法中使用@ConditionalOnMissingBean(name = “redisTemplate”),即Spring容器中不存在beanName为redisTemplate的Bean时,将该方法的返回值template,以redisTemplate作为beanName,注册到Spring容器。

三、SpringBoot对@Conditional的拓展

  • SpringBoot提供了自动配置功能。针对某个功能组件,以应用代码自身提供的为准,即如果应用代码提供了该功能组件,则以应用代码的为准,没有则自动加载一个默认的到Spring容器。或者为某个功能组件,自动配置一个依赖组件。
  • SpringBoot通过拓展@Conditional注解,派生更多语义明确的条件注解,以及定义对应的Condition接口实现类来处理判断逻辑。

1. 类级别

  • @ConditionalOnClass:判断类路径是否存在指定类、类的子类,接口实现类等,存在则返回true,继续执行;如RedisAutoConfiguration配置类的@ConditionalOnClass(RedisOperations.class);
  • @ConditionalOnMissingClass:与@ConditionalOnClass语义相反,不存在时返回true;
  • 对应的Condition接口实现类为OnClassCondition。

2.Bean级别(基于BeanFactory包含的BeanDefinition)

  • @ConditionalOnBean:判断当前Spring容器存在指定类对应的BeanDefinition,存在则返回true;
  • @ConditionalOnMissingBean:与ConditionalOnBean语义相反;
  • 对应的Condition接口实现类为OnBeanCondition。

3.其他

  • @ConditionalOnProperty(属性级别)、@ConditionalOnResource(资源级别)等。
发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();