@SpringBootApplication是Springboot項目最為重要的注解,我們面試的時候經常被問到。其實不管是面試與否,作為一名java開發人員,還是有必要搞清楚springboot的核心注解。
1.關于Springboot項目的啟動和自動配置問題
自動配置:根據我們添加的jar包依賴,會自動将一些配置類的bean注冊進ioc容器,我們可以需要的地 方使用@autowired或者@resource等注解來使用它。
Spring Boot到底是如何進行自動配置的,都把哪些元件進行了自動配置?
1)Spring Boot應用的啟動入口是@SpringBootApplication注解标注類中的main()方法。
2)@SpringBootApplication 标注在某個類上說明這個類是 SpringBoot 的主配置 類, SpringBoot 就應該運作這個類的 main() 方法啟動 SpringBoot 應用。
[email protected]
下面,檢視@SpringBootApplication内部源碼進行分析 ,核心代碼具體如下:
@Target(ElementType.TYPE) //注解的适用範圍,Type表示注解可以描述在類、接口、注解或枚舉中
@Retention(RetentionPolicy.RUNTIME) //表示注解的生命周期,Runtime運作時
@Documented //表示注解可以記錄在javadoc中
@Inherited //表示可以被子類繼承該注解
//------------------------------------------------
@SpringBootConfiguration // 标明該類為配置類
@EnableAutoConfiguration // 啟動自動配置功能
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) //注解掃描
public @interface SpringBootApplication {
// 根據class來排除特定的類,使其不能加入spring容器,傳入參數value類型是class類型。
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
// 根據classname 來排除特定的類,使其不能加入spring容器,傳入參數value類型是class的全類名字元串數組
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
// 指定掃描包,參數是包名的字元串數組。
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
// 掃描特定的包,參數類似是Class類型數組。
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
從上述源碼可以看出,@SpringBootApplication注解是一個組合注解,前面 4 個是注解的元注解, 我們主要看後面 3 個注解:@SpringBootConfiguration、@EnableAutoConfiguration、 @ComponentScan三個核心注解,關于這三個核心注解的相關說明具體如下:
[email protected]
@SpringBootConfiguration : SpringBoot 的配置類,标注在某個類上,表示這是一個 SpringBoot 的配置類。 檢視@SpringBootConfiguration注解源碼,核心代碼具體如下。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration//配置類的作用等同于配置檔案,配置類也是容器中的一個對象
public @interface SpringBootConfiguration {
...
}
從上述源碼可以看出,@SpringBootConfiguration注解内部有一個核心注解@Configuration,該注解 是Spring架構提供的,表示目前類為一個配置類(XML配置檔案的注解表現形式),并可以被元件掃描 器掃描。由此可見,@SpringBootConfiguration注解的作用與@Configuration注解相同,都是辨別一 個可以被元件掃描器掃描的配置類,隻不過@SpringBootConfiguration是被Spring Boot進行了重新封 裝命名而已。
[email protected]
源碼如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage // 自動配置包
@Import(AutoConfigurationImportSelector.class) // Spring的底層注解@Import,給容器中導入一個元件;
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
1)@AutoConfigurationPackage自動裝配包注解,也是一個組合注解,底層也是包含@Import注解。
2)@Import導入注解,也就是給容器導入一個元件。Spring 中有很多以 Enable 開頭的注解,其作用就是借助 @Import 來收集并注冊特定場景相關的 Bean ,并加載到 IOC 容器。
3)@EnableAutoConfiguration就是借助@Import來收集所有符合自動配置條件的bean定義,并加載到 IoC容器。
其中,@AutoConfigurationPackage和@Import非常重要,下次在講解。
[email protected]
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
...
}
注解@ComponentScan就是開始包掃描的注解,我們寫業務代碼的時候,想注解生效,必須開啟包掃描,就是這個注解。其實就是對應的傳統springmvc中如下配置:
<context:component-scan base-package="com.alibaba.*"></context:component-scan>