SpringBoot入口類和@SpringBootApplication詳解
SpringBoot專案建立完成之後預設會生成一個*Application的入口類,通過該類的main方法即可啟動SpringBoot專案。
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class SpringbootRunApplication { public static void main(String[] args) { SpringApplication.run(SpringbootRunApplication.class, args); } }
在此入口類中,我們可以看到SpringBoot建立的業務程式碼中(除單元測試)唯一的一個註解——@SpringBootApplication ,這也是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 { /** * 根據類排除不使用的自動配置 */ @AliasFor(annotation = EnableAutoConfiguration.class) Class<?>[] exclude() default {}; /** * 根據類名排除不使用的自動配置 */ @AliasFor(annotation = EnableAutoConfiguration.class) String[] excludeName() default {}; /** * 指定掃描的包 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") String[] scanBasePackages() default {}; /** * 指定掃描的類 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") Class<?>[] scanBasePackageClasses() default {}; }
該註解自身為我們提供了四個可配置項:
- exclude:根據類排除不使用的自動配置;
- excludeName:根據類名排除不使用的自動配置;
- scanBasePackages:掃描指定的包;
- scanBasePackageClasses:掃描指定的類;
@SpringBootApplication 組合了@SpringBootConfiguration 、@EnableAutoConfiguration 、@ComponentScan ,因此我們也可以直接使用這三個註解來替代它。
在早期版本並沒有@SpringBootConfiguration ,之後使用了@SpringBootConfiguration 並在其中組合了@Configuration 註解。在@EnableAutoConfiguration 註解中組合了@AutoConfigurationPackage 。
@ComponentScan 相關使用
@ComponentScan 用來指定掃描的組建所在的包路徑或class檔案。在不指定引數的時候,SpringBoot的@ComponentScan 預設會掃描同目錄及同目錄下級目錄的類檔案。通過部分原始碼我們可以明確的看到。
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Repeatable(ComponentScans.class) public @interface ComponentScan { @AliasFor("basePackages") String[] value() default {}; @AliasFor("value") String[] basePackages() default {}; ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT; String resourcePattern() default “**/*.class"; // 省略掉部分原始碼 }
上面的原始碼重點看一下屬性resourcePattern的預設值“*/ .class”,可以看出,如果不指定其他引數的話,預設會去尋找同級目錄下的class。
在構造SpringBoot專案時,往往會出現這樣一種情況:因為忘記或不知道SpringBoot預設掃描的路徑,隨意建立包和類的位置,導致專案啟動之後,無法例項化對應的組建,無法正確訪問介面。
當然,如果是有意為之,那麼我們就可以使用@SpringBootApplication 或@ComponentScan 來指定一些特殊的需要例項化的包或類。
@SpringBootApplication(scanBasePackages = “com.secbro2.controller") // 或 @ComponentScan(basePackages = "com.secbro2.controller")
@EnableAutoConfiguration
@EnableAutoConfiguration 讓SpringBoot可以根據類路徑中的jar包依賴可以為專案進行一些自動配置。這也是SpringBoot最核心的功能。當然,前提條件是依賴需要按照starter的規則來構建。
比如,我們添加了web的starter,那麼SpringBoot就會自動新增Tomcat和SpringMVC的依賴,然後又會進行一些相應的預設配置。但有些依賴需要我們自己去配置一些內容,比如雖然引入了data-jpa的starter,但是如果我們不配置對應的資料來源,程式肯定沒辦法正常啟動。
關閉自動配置
自動配置有它的便捷之處,但在某些情況下,我們可能並不需要一些自動配置。比如,雖然引入了data-jpa的依賴,但此刻並不需要連線資料庫。那麼,就可以通過註解將此自動配置進行關閉。@SpringBootApplication 為我們提供了相應的功能。
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
為什麼是SpringBoot
面試中可能會被問到:為什麼我們要使用SpringBoot?
你可能會說:因為SpringBoot用java配置替代了xml配置,或因為它內建Tomcat,可以直接打成jar包,通過java -jar快速啟動等;但這都不是重點,重點是剛剛說的@EnableAutoConfiguration 實現的功能:自動配置。基於程式設計的一個共識:約定優於配置。這也正是SpringBoot的核心。
回想一下,在使用SpringBoot的過程中,當用到某個元件,只需引入相應的依賴(starter)。此時SpringBoot已經幫我們把相關的依賴引入,配置好最基本的引數。然後我們根據需要再在application.yml檔案中配置一些明確的引數(比如:資料庫地址、使用者名稱等),就完成了一個元件的整合,可以專注業務程式碼的編寫了。
關注微信公眾:程式新視界,回覆“springbootrun”即可獲得本篇內容PDF版本,更多免費資料,期待你的到來。