1. Conditional注解介绍
Conditional注释是一种基于条件的注解,也就是根据某一个特定条件来决定是否创建某个特定的Bean,这是SpringBoot实现自动装配的基础原理。
常见的Conditional注解主要有:
- @ConditionalOnBean:存在某个bean才会生效
- @ConditionalOnMissingBean:不存在某个bean才会生效
- @ConditionalOnClass:存在某个class才会生效
- @ConditionalOnMissingClass:不存在某个class才会生效
- @ConditionalOnWebApplication:web环境才会生效
- @ConditionalOnNotWebApplication:非web环境才会生效
- @ConditionalOnProperty:存在某个属性才会生效
- @ConditionalOnJava:当前是处于哪个特定的java版本
在@Conditional注解里面有一个方法value,它要求value是一个Condition类型。Condition是一个接口,它里面只定义一个方法matches,如果该方法返回true就创建bean,false就不创建bean。因此我们自己也可以自定义自己的Conditional,具体步骤如下:
- 创建一个ConditionalOnXXX注解
- 创建一个类实现Condition接口,实现matches方法,该方法有2个参数,分别是ConditionContext和AnnotatedTypeMetadata,ConditionContext可以获取框架内的资源,如Environment、BeanFactory等;AnnotatedTypeMetadata是引用该类的注解所标注的类的注解元信息。
- 将该实现类引入到ConditionalOnXXX注解中
2. Starter介绍
Starter是一种可插拔的插件,而且它能够实现自动配置,大幅提升开发效率。而不像jar依赖,引入之后我们需要手动去配置类之前的依赖关系。使用starter可以自动为我们完成类的依赖配置。目前有很多starter可以供我们使用,如spring-boot-starter-web等。
当然我们也可以自定义starter,定义的流程如下:
3. Starter原理解析
Starter的导入原理:首先它依赖于启动类上的@SpringBootApplication注解,该注解引入了AutoConfigurationImportSelector,该类会被在ConfigurationClassParser中被处理,并获取spring.factories配置文件中所有实现了EnableAutoConfiguration的类,之后经过去重、排除等操作之后将剩下的class进行实例化。而ConfigurationClassParser调用的入口是在AbstractApplicationContext的refresh方法中,然后再调用PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessor方法,该方法中又回去调用invokeBeanDefinitionRegistryPostProcessors,此时就会调用ConfigurationClassPostProcesso的postProcessBeanDefinitionRegistry方法,最终调用到了ConfigurationClassParser的parse方法上。
在完成所有的自动装配配置文件的解析之后,然后查看配置文件的是否有Conditional注解,根据该注解所引入的Condition实现类的matches方法去判断是否改配置需要加载和实例化,matches结果为true就不加载,false就加载。