一.SpringBoot自动装配
SpringBoot 的 自动装配(Auto-Configuration) 是它的核心特性之一,它让开发者可以 "开箱即用",避免手动配置大量的 XML 或 Java Config。它的核心思想是:
"约定优于配置"(Convention Over Configuration)
"按需加载"(Conditional Loading)
简单理解就是"按需装配"——你有啥我就配啥,你缺啥我就补啥,你自己配了我就用你的。这样开发者只需要关注自己需要改的部分,其他都用合理的默认值。
那这些自动配置类如何注入到项目中呢?下面模拟了自动配置类注入的过程。
二.如何实现
1.简易版本
package com.example.springdemo.demos.a04;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.GenericApplicationContext;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/15 21:30*/
public class TestAutoConfiguration {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();context.registerBean("config",Config.class);//添加bean工厂后处理器context.registerBean(ConfigurationClassPostProcessor.class);context.refresh();for (String name:context.getBeanDefinitionNames()) {System.out.println(name);}}@Configuration //本项目配置类@Import({AutoConfiguration1.class,AutoConfiguration2.class})static class Config{}@Configurationstatic class AutoConfiguration1{@Beanpublic Bean1 bean1(){return new Bean1();}}@Configurationstatic class AutoConfiguration2{@Beanpublic Bean2 bean2(){return new Bean2();}}
}
Bean1
package com.example.springdemo.demos.a04;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/15 21:32*/
public class Bean1 {
}
Bean2
package com.example.springdemo.demos.a04;/*** @author zhou* @version 1.0* @description TODO* @date 2025/8/15 21:32*/
public class Bean2 {
}
自动注入配置类实现思路:
- 创建容器
- 添加bean工厂后处理器
- 创建配置类(项目所需特有配置类)
- 创建自动配置类(每个项目常用的公共类)
- 使用@Import注解导入自动配置类到项目配置类里面
- 输出结果
config
org.springframework.context.annotation.ConfigurationClassPostProcessor
com.example.springdemo.demos.a04.TestAutoConfiguration$AutoConfiguration1
bean1
com.example.springdemo.demos.a04.TestAutoConfiguration$AutoConfiguration2
bean2
容器里面不仅有我们自己的配置类,还有通过自动注入的配置类。
2.改进实现
使用MyImportSelector类导入自动配置类
@Configuration //本项目配置类@Import({MyImportSelector.class})static class Config{}
static class MyImportSelector implements ImportSelector{@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//返回配置类的类名return new String[]{AutoConfiguration1.class.getName(),AutoConfiguration2.class.getName()};}}
3.自动配置类写入配置文件
在resource的META-INF下新建一个spring.factories文件,key为导入类的类路径,值为自动配置类的类路径。
com.example.springdemo.demos.a04.TestAutoConfiguration.MyImportSelector=\
com.example.springdemo.demos.a04.TestAutoConfiguration.AutoConfiguration1,\
com.example.springdemo.demos.a04.TestAutoConfiguration.AutoConfiguration2
但是这里有一点比较特殊,我的导入类是一个内部类,键的最后的一个点得改为$,否则会失效。
com.example.springdemo.demos.a04.TestAutoConfiguration$MyImportSelector=\
com.example.springdemo.demos.a04.TestAutoConfiguration.AutoConfiguration1,\
com.example.springdemo.demos.a04.TestAutoConfiguration.AutoConfiguration2
MyImportSelector类通过SpringFactoriesLoader加载配置文件里面的类。这样就方便拓展,而不用写死。
static class MyImportSelector implements ImportSelector{@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//返回配置类的类名List<String> names = SpringFactoriesLoader.loadFactoryNames(MyImportSelector.class,null);return names.toArray(new String[0]);}}