SpringBoot啟動類@SpringBootApplication註解背後的祕密
在用SpringBoot的專案的時候,會發現不管幹什麼都離不開啟動類,他是程式唯一的入口,那麼他究竟為我們做了什麼?本篇文章主要解析@SpringBootApplication。
一、啟動類
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
二、@SpringBootApplication
@SpringBootApplication: Spring Boot應用標註在某個類上說明這個類是SpringBoot的主配置類,
SpringBoot 就應該執行這個類的main方法來啟動SpringBoot應用;
相關配置啟動都是由該註解來幫我們完成的,點進去了解一下
@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 { }
點進去會發現他的註解類當中還有很多註解,就是一個自定義組合註解。
接下來來對他組合的註解一一講解。
1、@Target(ElementType.TYPE)
@Target說明了Annotation(註解)所修飾的物件範圍
取值(ElementType)有:
1.CONSTRUCTOR:用於描述構造器
2.FIELD:用於描述域
3.LOCAL_VARIABLE:用於描述區域性變數
4.METHOD:用於描述方法
5.PACKAGE:用於描述包
6.PARAMETER:用於描述引數
7.TYPE:用於描述類、介面(包括註解型別) 或enum宣告
2、@Retention(RetentionPolicy.RUNTIME)
註解按生命週期來劃分可分為3類:
1、RetentionPolicy.SOURCE:註解只保留在原始檔,當Java檔案編譯成class檔案的時候,註解被遺棄;
2、RetentionPolicy.CLASS:註解被保留到class檔案,但jvm載入class檔案時候被遺棄,這是預設的生命週期;
3、RetentionPolicy.RUNTIME:註解不僅被儲存到class檔案中,jvm載入class檔案之後,仍然存在;
3、@Documented
這個註解只是用來標註生成javadoc的時候是否會被記錄。
在自定義註解的時候可以使用@Documented來進行標註,如果使用@Documented標註了,在生成javadoc的時候就會把@Documented註解給顯示出來。
4、@Inherited
@Inherited是一個標識,用來修飾註解,自定義註解當中會用到
首先自定義一個註解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface ATable { public String name() default ""; }
以下是在使用自定義註解的一個場景。
類繼承關係中@Inherited的作用
類繼承關係中,子類會繼承父類使用的註解中被@Inherited修飾的註解
@ATable public class InheritedBase { } public class MyInheritedClass extends InheritedBase { }
介面繼承關係中@Inherited的作用
介面繼承關係中,子介面不會繼承父介面中的任何註解,不管父介面中使用的註解有沒有被@Inherited修飾
@ATable public interface IInheritedInterface { } public interface IInheritedInterfaceChild extends IInheritedInterface { }
類實現介面關係中@Inherited的作用
類實現介面時不會繼承任何介面中定義的註解
@ATable public interface IInheritedInterface { } public class MyInheritedClassUseInterface implements IInheritedInterface { }
5、@SpringBootConfiguration
標註在某個類上,表示這是一個Spring Boot的配置類
點進去會發現,他其實也是一個自定義註解
@Configuration學spring的應該對他不陌生
作用:指定當前類是一個配置類,在使用spring的時候剛開始都是xml配置,也正是這個註解,開啟了類配置方式。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { }
6、@EnableAutoConfiguration
以前我們需要配置的東西,Spring Boot會幫我們自動配置;
@EnableAutoConfiguration告訴SpringBoot開啟自 動配置功能;這樣自動配置才能生效;
點進去會發現@Import,說白了他就是藉助@Import的支援,收集和註冊特定場景相關的bean定義。
@Import作用:用於匯入其他的配置類
而@EnableAutoConfiguration也是藉助@Import的幫助,將所有符合自動配置條件的bean定義載入到IoC容器,僅此而已!
@SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { }
EnableAutoConfigurationImportSelector:匯入哪些元件的選擇器;
會給容器中匯入非常多的自動配置類(xxxAutoConfiguration);
大概的流程就是:
Spring Boot在啟動的時候,通過EnableAutoConfigurationImportSelector類,從類路徑下的
META-INF/spring.factories中獲取EnableAutoConfiguration指定的值(就是上方截圖),
以全類名反射的建立方式,將這些值作為自動配置類匯入到容器中,自動配置類就生效,
幫我們進行自動配置工作;
以前我們需要自己配置的東西,自動配置類都幫我們配置好了,這也就是使用springboot在使用spring,springmvc不用配置檢視解析器、資料庫連線池、事務 等配置的原因。直接開箱即用。
當然springboot也給我提供了修改配置的方法,那就是通過yml或者propertie檔案來進行修改springboot為我們配置好的配置預設值。
7、@ComponentScan
作用:用於通過註解指定spring在建立容器時要掃描的包
我們可以通過basePackages等屬性來細粒度的定製@ComponentScan自動掃描的範圍,如果不指定,則預設Spring框架實現會從宣告@ComponentScan所在類的package進行掃描。
@ComponentScan("com.gzl")
這也就是springboot啟動類為什麼放在包外的原因。
三、不使用這個註解能否啟動專案
把@SpringBootApplication換成以下三個註解,照樣可以正常啟動。
package com.gzl.cn; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
到此這篇關於SpringBoot啟動類@SpringBootApplication註解背後的祕密的文章就介紹到這了,更多相關@SpringBootApplication註解背後的祕密內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!