1. 程式人生 > 實用技巧 >2020-11-01 助教一週總結(第九周)

2020-11-01 助教一週總結(第九周)

SpringBoot自動裝配原理解析:

轉載自https://www.cnblogs.com/lzh-boke/p/11876679.html

註解結構:

  

入口點:SpringBoot的引導類有如下內容:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
      SpringApplication.run(Application.class,args);
   }
}

@SpringBootApplication註解:

進入@SpringBootApplication的註解類,會發現@SpringBootApplication是一個組合註解,在所包含的註解中重點要

關注如下三個註解:@SpringBootConfifiguration、@EnableAutoConfifiguration、@ComponentScan

程式碼示例:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes =
AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
.....
}

@SpringBootConfifiguration註解:

程式碼例項:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

經過檢視會發現在該註解類上有一個大家比較熟悉的註解@Confifiguration,該註解是用來標識某一個類為Spring的

一個配置類,所以@SpringBootConfifiguration和@Confifiguration註解的作用一樣,但是SpringBoot更推薦使用

@SpringBootConfifiguration.

@EnableAutoConfifiguration註解:

程式碼示例:

1 @Target(ElementType.TYPE)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Inherited
5 @AutoConfigurationPackage
6 @Import(AutoConfigurationImportSelector.class)
7 public @interface EnableAutoConfiguration {
8   ......
9 }

經過檢視可發現@EnableAutoConfifiguration也是一個組合註解,其中有兩個註解需要重點理解下,如

@AutoConfifigurationPackage和@Import

@AutoConfifigurationPackage註解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}

經過檢視可發現該註解通過@Import引入了一個Registrar.class類,那麼該類實現了什麼功能?在Registrar類中的

registerBeanDefifinitions方法上打個斷點,debug啟動後,會發現該類主要是載入@SpringBootApplication註解所

在類的包結構,並進行儲存,為後期SpringBoot載入資源提供一個掃描的包路徑。

@Import(AutoConfifigurationImportSelector.class)

上述@Import註解引入了一個類AutoConfifigurationImportSelector.class,讀取該類的原始碼會發現,SpringBoot啟

動所在的裝配類都在該註解類所在專案的META-INF/spring.factories檔案中讀取

通過debug啟動後,會發現預設情況下會載入109個自動裝配類,剛好對應的是spring.factoires檔案中的自動裝配類 的數量

META-INF/spring.factories中的內容

自動裝配類解析:

我們可以從中抽取一個類,如:

org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration

開啟DispatcherServletAutoConfifiguration看看如下:

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
@EnableConfigurationProperties(ServerProperties.class)
public class DispatcherServletAutoConfiguration {
    ......
}   
上面的是關於DispatcherServletAutoConfifiguration的定義,通過原始碼我們發現在這個類上定義了好幾個註解,其中:
@Confifiguration
@Bean 這兩個註解的作用就是在Spring容器中將需要用到的Bean物件進行建立。
@AutoConfifigureOrder
@AutoConfifigureAfter
@AutoCOnfifigureBefore這三個註解,主要是指定當前類自動裝配的順序和時機。
@ConditionalOnWebApplication :這是一個條件註解,當前專案是web環境的條件下
@ConditionalOnClass:當前類路徑下有指定的類的條件下。
分析完這些註解我們應該能明白的是sprinboot中的自動配置其實是使用這些條件註解來完成,當滿足指定條件後就
可以自動進行配置

常見的條件註解:

@ConditionalOnBean          當容器中存在指定bean的條件下
@ConditionalOnClass         當類路徑下存在指定類的條件下
@ConditionalOnMissingBean     當容器中不存在指定bean的條件下
@ConditionalOnMissingClass    當類路徑下不存在指定類的條件下
@ConditionalOnProperty       指定的屬性是否存在指定的值
@ConditionalOnResource       類路徑下是否有指定的值
@ConditionalOnWebApplication   是web環境的條件下下
@ConditionalOnNotWebApplication 不是web環境的條件下

轉載自https://www.cnblogs.com/lzh-boke/p/11876679.html