SpringBoot自动装配原理(学习笔记)
原理总结一句话就是:通过@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注解
@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的实现类
public class ConditionRedis implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
boolean flag=false;
try {
Class<?> aClass = Class.forName("org.springframework.data.redis.core.RedisTemplate");
flag=true;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return flag;
}
}
-
导入redis的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
-
Springboot入口类测试
@SpringBootApplication
public class SpringBootCondition {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(SpringBootCondition.class, args);
User bean = run.getBean(User.class);
System.out.println(bean);
}
}
效果 没有导入导入了redis依赖 导入了redis依赖
EnableAutoConfiguration原理
- 主要的注解是@EnableAutoConfiguration
- @EnableAutoConfiguration注解上面又使用了@Import({AutoConfigurationImportSelector.class})注解,映入了AutoConfigurationImportSelector类
- AutoConfigurationImportSelector类中调用了selectImports类
- selectImports调用了
源码注解 根据导入的@Configuration类的AnnotationMetadata返回AutoConfigurationImportSelector.AutoConfigurationEntry 。 参数: annotationMetadata – 配置类的注解元数据 返回: 应该导入的自动配置 - 调用了getCandateConfigurations()方法
- 读取配置文件
|