3. SpringBoot自动装配原理
大约 3 分钟
3. SpringBoot自动装配原理
一、概述
SpringBoot的自动装配是其核心特性之一,它能够根据引入的依赖自动配置Spring应用。本章节将详细解释SpringBoot的自动装配原理,包括bean的创建、条件判断、Enable注解原理等。
二、知识要点
1. bean的创建与条件判断
SpringBoot使用@Conditional注解来判断是否创建某个bean。
@Conditional(OnBeanCondition.class)
// 下面的注解都被@Conditional修饰执行()中不同类的条件判断方法
@ConditionalOnClass // 存在类则为满足条件创建bean
@ConditionalOnMissingBean // 不存在则满足条件创建bean
条件判断的实现过程:
- 先获取@ConditionalOnClass注解
- 再获取被@ConditionalOnClass注解标识的value值(存有字节码文件.class)
- 遍历value数组加载字节码对象,加载成功则返回true顺利创建bean,其中有加载失败则表明没有该字节码文件,返回falsebean创建失败
2. 内置服务器的切换
springboot内置了四种服务器当导入不同的依赖时,会自动装配不同的服务器。
<!-- 排除tomcat依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加jetty依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
3. Enable注解原理
SpringBoot提供了@Eable*注解用于动态加载bean,原理就是在注解上加入了@Import注解并导入了一些配置类。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyConfig.class)
public @interface EnableMyFeature {
}
4. @Import原理
@Import():导入的类会被Spring加载到IOC容器中
- 导入一个bean类对象直接加载到中IOC容器中
- 导入一个配置类,加载配置类文件加载bean
- 导入一个ImportSelector自定义实现类,根据全路径类名加载多个bean到IOC容器中
- 导入一个ImportBeanDefinitionRegistrar自定义实现类,加载指定类注册到IOC容器中
5. @EnableAutoConfiguration注解
- 在启动类上@SpringBootApplication中有标识@EnableAutoConfiguration注解表示自动配置。
- 当启动项目时,会加载这个注解内部中的@Import(AutoConfigurationImportSelector.class)装载的类。
- 该类AutoConfigurationImportSelector.class主要是会去加载配置文件META-INF/spring.factories,该配置文件中定义了大量的配置类。
- 但不会所有配置都会加载而是有条件的加载,满足@Conditional()的配置文件会被加载。
三、知识扩展
1. 设计思想
- 约定大于配置:通过默认配置减少开发者的配置工作
- 条件装配:根据条件动态装配bean,避免不必要的资源消耗
- 模块化:通过Enable注解实现功能模块的按需加载
- 扩展性:通过ImportSelector和ImportBeanDefinitionRegistrar提供灵活的扩展机制
2. 避坑指南
- 不要随意修改META-INF/spring.factories文件
- 不要忽略@Conditional注解的条件,可能导致bean无法创建
- 不要在同一应用中使用多个冲突的Enable注解
- 不要忘记@SpringBootApplication注解,它是自动装配的入口
3. 深度思考题
** 思考题:** SpringBoot是如何知道要创建哪个bean的? ** 回答:** SpringBoot通过@EnableAutoConfiguration注解导入AutoConfigurationImportSelector类,该类会加载META-INF/spring.factories文件中的配置类,然后根据@Conditional注解的条件判断是否创建对应的bean。
** 思考题:** 如何自定义一个Enable注解? ** 回答:** 可以通过创建一个注解,并在该注解上添加@Import注解导入一个配置类,然后在配置类中定义需要加载的bean。例如:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyConfig.class)
public @interface EnableMyFeature {
}
@Configuration
public class MyConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
然后在启动类上添加@EnableMyFeature注解就可以加载MyService这个bean了。