天天看點

Springboot的核心注解@SpringBootApplication

@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>