一.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]);}}