我們在使用Spring框架中,特別是框架級的功能,經常看到有@Import導入功能,
我就介紹下它能導入什么,首先聲明下@Import是注解,導入類型可分為三類:
1. 導入配置 @Configuration,類似於spring早期版本2.5的import xml文件一樣,
只是現在注解搶了風頭,但目的一樣,用於使用所有標有@configuration注解的配置。
下面我就寫個小例子,怎么建java項目就略了
先建java主包com.spring, 然后分別建子包
1.1 建立服務接口
1.2 建立服務實現類,分三種情況,控制台、文件和數據庫mysql
1.3 寫配置類,三個服務實現類對應三個@Configuration
然后@Import注解登場了
1.4 建立測試類看效果
輸出效果
2. 導入實現ImportSelector接口或子接口DeferredImportSelector的類
@Import annotation can also be configured with an ImportSelector implementation to select @Configuration classes programmatically, based on some selection criteria.
下面我也演示下,這個很重要,框架里和spring擴展開發用的多,先建立備用子包com.spring.bean和com.spring.importSelector,然后建立配置文件目錄conf
2.1 實現了ImportSelector
2.1.1 建立輔助類ApplicationProperties.java和外置配置文件myapp.properties
然后在conf目錄下建立配置文件myapp.properties,內容如下:
2.1.2 建立@Configuration配置類
2.1.3 建立實現了ImportSelector接口的導入類,返回列表里的值是有標志@Configuration
2.1.4 建立有@import功能的配置類,導入2.1.3的實現類
2.1.5 編寫測試類
輸出效果:
效果不錯,也能完成bean的注冊
還有一種基於注解的變體,我也示例下,先建個子包com.spring.annotation
建立自定義注解:
然后修改導入選擇器實現類,根據啟用日志功能時傳的參數絕對加載哪個bean
修改配置類,追加自定義注解@EnableLogService,並設置參數為file(可選stdout,file,mysql)
修改測試類,此時不再是三種日志實現的bean都加載,按配置參數加載
就因為配置了@EnableLogService(logType="file"),只加載了一個日志實現bean
2.2 實現了 DeferredImportSelector
可是看出它是2.1的子接口
The configuration class directly registered with the application context given preference over imported one. That means a bean of type T, configured in the main configuration will be used instead of a bean of the same type T from imported configuration. That applies to ImportSelector as well. On the other hand, DeferredImportSelector applies after all other configuration beans have been processed.
我們可以比較下實現兩種接口的區別
在主選擇器的配置類LogImportSelectorConfig.java中增加
在文件配置類FileLogConfig.java中修改為
選擇器實現類還是
執行測試代碼
此時修改選擇器實現的接口改為DeferredImportSelector,其它不改
再次執行測試
3 導入實現了ImportBeanDefinitionRegistrar接口的類
可以先瞄下接口的如何定義和定義了什么
This Interface is to be implemented by types that register additional bean definitions when processing @Configuration classes.
具體可參考還記得我以前寫的博文Spring Bean注冊的幾種方式https://blog.csdn.net/dong19891210/article/details/105798650嗎,詳細看第5.2小節,這里就不再重復啰嗦寫了。
想了幾天還是花點時間寫上,畢竟放到個人電腦上不安全,我就一步一步開始完善
3.1 建立自定義組件注解標識和掃描包注解
然后再建掃描包注解
重點看@Import(CustomImportBeanDefinitionRegistrar.class)
3.2 定義實現了ImportBeanDefinitionRegistrar接口的類
3.3 定義配置類,預設組件掃描的包是com.spring.mapper
3.4 建立自定義組件掃描的包com.spring.mapper,略
然后在自定義包下建立自定義組件,注意類上有自定義組件標識@CustomComponent
3.5 編寫測試
注意:引入兩個配置類MysqlDatabaseConfiguration和CustomComponentConfiguration(由於MysqlDatabaseConfiguration關聯代碼多,所以沒有在文章里寫,測試時可去掉不引入MysqlDatabaseConfiguration.class)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
MysqlDatabaseConfiguration.class, CustomComponentConfiguration.class);
輸出效果:
其實你搞懂了Bean,spring本身、及衍生的第三方擴展, 99.99%的問題都不再是問題了!!!
小結:一圖
務必掌握好2和3,寫擴展很有用,甚至spring本身都在大量使用,如下



spring圍繞着bean運轉的,注冊的幾種方式,每種注冊方式的條件性選擇
最后請慢慢學會忘記xml格式的配置文件,現在或往后都是注解式了,雖然xml配置並不影響功能!
附部分注解圖一張:
參考:
0. @Import Annotation in Spring Framework
https://javabeat.net/use-import-importing-javaconfig-files-spring-projects/
1. Spring向容器注冊Bean的高級應用 https://cloud.tencent.com/developer/article/1497795
2. how spring import annotation parse(要FQ) https://laptrinhx.com/spring-import-annotation-source-parsing-3074679655/
注意我說的牆不是下面這樣的牆









