天津自己制作網(wǎng)站網(wǎng)站新站整站排名
SPI
spi : service provider interface : 是java的一種服務(wù)提供機(jī)制,spi 允許開發(fā)者在不修改代碼的情況下,為某個(gè)接口提供實(shí)現(xiàn)類,來(lái)擴(kuò)展應(yīng)用程序
將實(shí)現(xiàn)類獨(dú)立到配置文件中,通過(guò)配置文件控制導(dǎo)入:
public static void main(String[] args) {ServiceLoader<Animal> load = ServiceLoader.load(Animal.class);for (Animal animal : load) {animal.sound();}}
就會(huì)導(dǎo)入Animal的兩個(gè)實(shí)現(xiàn)類
問(wèn)題:
- spi 和一般的面向接口變成有什么區(qū)別?,,使用spi導(dǎo)入和直接用,不是一樣的嗎
- 動(dòng)態(tài)加載實(shí)現(xiàn)類
在一般的面向接口變成中,通常需要顯示的創(chuàng)建實(shí)現(xiàn)類,,,通過(guò)spi機(jī)制,可以在運(yùn)行時(shí)動(dòng)態(tài)加載實(shí)現(xiàn)類,無(wú)需在代碼中指定具體的實(shí)現(xiàn)類,代碼更加靈活可擴(kuò)展 - 配置文件
一般在面向接口編程中,通常在代碼中顯示的指定具體的實(shí)現(xiàn)類,,顯示的注入實(shí)現(xiàn)類,,而spi使用配置文件META-INF/services
指定接口實(shí)現(xiàn)類,如果要新增或者切換實(shí)現(xiàn)類,那么只需要修改配置文件即可,,
- 動(dòng)態(tài)加載實(shí)現(xiàn)類
spi使得應(yīng)用程序設(shè)計(jì),更具靈活性,模塊化,可擴(kuò)展性,,它通過(guò)動(dòng)態(tài)加載實(shí)現(xiàn)類,解耦接口和實(shí)現(xiàn),以及使用配置文件來(lái)實(shí)現(xiàn)這些特性,,從而使得應(yīng)用程序更加智能的加載,和使用模塊
springboot自動(dòng)裝配
springboot自動(dòng)裝配是 SPI 思想的一種應(yīng)用
@SpringbootApplication
: 聲明這個(gè)類是個(gè)引導(dǎo)類,或者叫 配置類
是一個(gè)復(fù)合注解
- @SpringbootConfiguration
- @ComponentScan : 掃描當(dāng)前包下 及其子包的 @Component 標(biāo)記的類
- @EnableAutoConfiguration
自動(dòng)裝配里面用了 @Import 和 ImportSelector接口,,
@Import和ImportSelector使用
創(chuàng)建了一個(gè)配置類 :
@Configuration
public class MyConfig {@Beanpublic Watermelon watermelon(){return new Watermelon();}
}
可以使用 @Import(MyConfig.class) 直接導(dǎo)入配置類,
//@ComponentScan
// @Import(MyConfig.class)@Import(FruitConfigurationSelector.class)
public class FruitApplication {public static void main(String[] args) {// 默認(rèn)啟動(dòng)web服務(wù)器,@ComponentScan會(huì)去掃web服務(wù)器ConfigurableApplicationContext context = new SpringApplicationBuilder(FruitApplication.class).web(WebApplicationType.NONE) // 關(guān)閉web服務(wù)器.run(args);Watermelon watermelon = (Watermelon) context.getBean("watermelon");System.out.println("watermelon = " + watermelon);}
}
也可以使用 @Import 導(dǎo)入 ImportSelector 的實(shí)現(xiàn)類,,這個(gè)實(shí)現(xiàn)類返回一個(gè)數(shù)組,表示要注入的bean的全限定類名的集合
public class FruitConfigurationSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{MyConfig.class.getName()};}}
@EnableXXXAutoConfiguration
寫一個(gè)注解,在這個(gè)注解上面,使用@Import 導(dǎo)入若干要導(dǎo)入的Bean,,
為什么要有@EnableXXXAutoConfiguration : 模塊裝配
,如果同時(shí)需要幾個(gè)模塊,使用@EnableXXXAutoConfiguration 裝配整合成一個(gè)
springboot中@EnableAutoConfiguration
ImportSelector 中的 selectImports方法
去導(dǎo)入bean,,
getCandidateConfigurations方法
去加載 spring.factories
中的配置,,預(yù)選配置再根據(jù)@Conditional去判斷哪些要注入容器