大致流程原理总结一句话就是:通过@EnableAutoConfiguration注解加载Springboot内置的自动初始化类(加载什么类是配置在Spring.factories),在这些类中基于spring4.0提供的Condition接口进行Bean的初始化。
从启动类的注解@SpringBootApplication中,除元注解以外最关键的注解是:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan。通过@EnableAutoConfiguration注解里面关键的是这个@import(AutoConfigurationimportSelector.class)这个注解,导入了一个AutoConfigurationimportSelector类。此类的作用就是扫描MATA-INFO/Spring.factories,以EnableAutoConfiguration下面的类的全路径,再 结合@Condition注解来判断是否注入该类。
@Conditional(条件判断)介绍@Conditional注解
-
作用:条件判断
-
使用:
-
可以写在类上或者方法上
-
参数是一个Class数组但传入的参数需要是Condition的实现类
-
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface Conditional {
Class extends Condition>[] value();
}
案例
需求:
- 创建一个配置类
- 编写一个方法,方法的返回值是User对象
- 在方法上使用@Condition注解,如果有redis则创建,没有redis则不创建
实现
-
创建一个配置类,并创建一个方法根据@Conditional注解,判断是否注入到Ioc容器中
//声明这是一个配置类 @Configuration public class ConditionTest { @Bean @Conditional(ConditionRedis.class) public User getUser(){ return new User(); } } -
创建一个Condition的实现类
//创建一个配置类,实现Condition接口 public class ConditionRedis implements Condition { //重写matches方法 返回值是false还是true,如果是tue则会注入到ioc容器中,如果是false则不会注入到ioc容器中 @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypemetadata annotatedTypemetadata) { boolean flag=false; try { //判断RedisTemplate是否导入了这个类 Class> aClass = Class.forName("org.springframework.data.redis.core.RedisTemplate"); //如果执行到这里说明是导入了 flag=true; } catch (ClassNotFoundException e) { //如果出现异常说明是没有导入这个类 e.printStackTrace(); } return flag; } } -
导入redis的依赖
org.springframework.boot spring-boot-starter-data-redis -
Springboot入口类测试
@SpringBootApplication
public class SpringBootCondition {
public static void main(String[] args) {
//得到ioc容器
ConfigurableApplicationContext run = SpringApplication.run(SpringBootCondition.class, args);
//从ioc容器中找User这个Bean
User bean = run.getBean(User.class);
//打印
System.out.println(bean);
}
}
效果
没有导入导入了redis依赖
导入了redis依赖
- 主要的注解是@EnableAutoConfiguration
- @EnableAutoConfiguration注解上面又使用了@import({AutoConfigurationimportSelector.class})注解,映入了AutoConfigurationimportSelector类
- AutoConfigurationimportSelector类中调用了selectimports类
- AutoConfigurationimportSelector类中调用了selectimports类
- selectimports调用了
源码注解
根据导入的@Configuration类的Annotationmetadata返回AutoConfigurationimportSelector.AutoConfigurationEntry 。
参数:
annotationmetadata – 配置类的注解元数据
返回:
应该导入的自动配置
- 调用了getCandateConfigurations()方法
- 读取配置文件



