SpringBoot啟動(dòng)原理深入解析
我們開發(fā)任何一個(gè) Spring Boot 項(xiàng)目,都會(huì)用到如下的啟動(dòng)類
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args);}}
從上面代碼可以看出,Annotation 定義(@SpringBootApplication)和類定義(SpringApplication.run)最為耀眼,所以要揭開 SpringBoot 的神秘面紗,我們要從這兩位開始就可以了。
一、SpringBootApplication 背后的秘密
@SpringBootApplication 注解是 Spring Boot 的核心注解,它其實(shí)是一個(gè)組合注解:
1 @Target(ElementType.TYPE) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Inherited 5 @SpringBootConfiguration 6 @EnableAutoConfiguration 7 @ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication {...}
雖然定義使用了多個(gè) Annotation 進(jìn)行了原信息標(biāo)注,但實(shí)際上重要的只有三個(gè) Annotation:
- @Configuration(@SpringBootConfiguration 點(diǎn)開查看發(fā)現(xiàn)里面還是應(yīng)用了 @Configuration)
- @EnableAutoConfiguration
- @ComponentScan
即 @SpringBootApplication = (默認(rèn)屬性)@Configuration + @EnableAutoConfiguration + @ComponentScan。
所以,如果我們使用如下的 SpringBoot 啟動(dòng)類,整個(gè) SpringBoot 應(yīng)用依然可以與之前的啟動(dòng)類功能對等:
@Configuration @EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args);}}
每次寫這 3 個(gè)比較累,所以寫一個(gè) @SpringBootApplication 方便點(diǎn)。接下來分別介紹這 3 個(gè) Annotation。
1、@Configuration
? 這里的 @Configuration 對我們來說不陌生,它就是 JavaConfig 形式的 Spring Ioc 容器的配置類使用的那個(gè) @Configuration,SpringBoot 社區(qū)推薦使用基于 JavaConfig 的配置形式,所以,這里的啟動(dòng)類標(biāo)注了 @Configuration 之后,本身其實(shí)也是一個(gè) IoC 容器的配置類。
舉幾個(gè)簡單例子回顧下,XML 跟 config 配置方式的區(qū)別:
(1)表達(dá)形式層面
基于 XML 配置的方式是這樣:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" default-lazy-init="true"> <!--bean定義--> </beans>
而基于 JavaConfig 的配置方式是這樣:
@Configuration public class MockConfiguration{ //bean定義 }
任何一個(gè)標(biāo)注了 @Configuration 的 Java 類定義都是一個(gè) JavaConfig 配置類。
(2)注冊 bean 定義層面
基于 XML 的配置形式是這樣:
<bean> ... </bean>
而基于 JavaConfig 的配置形式是這樣的:
@Configuration public class MockConfiguration{ @Bean public MockService mockService(){ return new MockServiceImpl();}}
任何一個(gè)標(biāo)注了 @Bean 的方法,其返回值將作為一個(gè) bean 定義注冊到 Spring 的 IoC 容器,方法名將默認(rèn)成該 bean 定義的 id。
(3)表達(dá)依賴注入關(guān)系層面
為了表達(dá) bean 與 bean 之間的依賴關(guān)系,在 XML 形式中一般是這樣:
<bean> <propery name ="dependencyService" ref="dependencyService" /> </bean> <bean></bean>
而基于 JavaConfig 的配置形式是這樣的:
@Configuration public class MockConfiguration{ @Bean public MockService mockService(){ return new MockServiceImpl(dependencyService()); } @Bean public DependencyService dependencyService(){ return new DependencyServiceImpl(); } }
如果一個(gè) bean 的定義依賴其他 bean,則直接調(diào)用對應(yīng)的 JavaConfig 類中依賴 bean 的創(chuàng)建方法就可以了。
@Configuration:提到 @Configuration 就要提到他的搭檔 @Bean。使用這兩個(gè)注解就可以創(chuàng)建一個(gè)簡單的 spring 配置類,可以用來替代相應(yīng)的 xml 配置文件。
<beans> <bean id = "car"> <property ></property> </bean> <bean id = "wheel"> </bean> </beans>
相當(dāng)于:
@Configuration public class Conf { @Bean public Car car() { Car car = new Car(); car.setWheel(wheel()); return car; } @Bean public Wheel wheel() { return new Wheel(); } }
@Configuration 的注解類標(biāo)識(shí)這個(gè)類可以使用 Spring IoC 容器作為 bean 定義的來源。
@Bean 注解告訴 Spring,一個(gè)帶有 @Bean 的注解方法將返回一個(gè)對象,該對象應(yīng)該被注冊為在 Spring 應(yīng)用程序上下文中的 bean。
2、@ComponentScan
? @ComponentScan 這個(gè)注解在 Spring 中很重要,它對應(yīng) XML 配置中的元素,@ComponentScan 的功能其實(shí)就是自動(dòng)掃描并加載符合條件的組件(比如 @Component 和 @Repository 等)或者 bean 定義,最終將這些 bean 定義加載到 IoC 容器中。
我們可以通過 basePackages 等屬性來細(xì)粒度的定制 @ComponentScan 自動(dòng)掃描的范圍,如果不指定,則默認(rèn) Spring 框架實(shí)現(xiàn)會(huì)從聲明 @ComponentScan 所在類的 package 進(jìn)行掃描。
注:所以 SpringBoot 的啟動(dòng)類最好是放在 root package 下,因?yàn)槟J(rèn)不指定 basePackages。
3、@EnableAutoConfiguration
個(gè)人感覺 @EnableAutoConfiguration 這個(gè) Annotation 最為重要,所以放在最后來解讀,大家是否還記得 Spring 框架提供的各種名字為 @Enable 開頭的 Annotation 定義?比如 @EnableScheduling、@EnableCaching、@EnableMBeanExport 等,@EnableAutoConfiguration 的理念和做事方式其實(shí)一脈相承,簡單概括一下就是,借助 @Import 的支持,收集和注冊特定場景相關(guān)的 bean 定義。
- @EnableScheduling 是通過 @Import 將 Spring 調(diào)度框架相關(guān)的 bean 定義都加載到 IoC 容器。
- @EnableMBeanExport 是通過 @Import 將 JMX 相關(guān)的 bean 定義加載到 IoC 容器。
而 @EnableAutoConfiguration 也是借助 @Import 的幫助,將所有符合自動(dòng)配置條件的 bean 定義加載到 IoC 容器,僅此而已!
@EnableAutoConfiguration 會(huì)根據(jù)類路徑中的 jar 依賴為項(xiàng)目進(jìn)行自動(dòng)配置,如:添加了 spring-boot-starter-web 依賴,會(huì)自動(dòng)添加 Tomcat 和 Spring MVC 的依賴,Spring Boot 會(huì)對 Tomcat 和 Spring MVC 進(jìn)行自動(dòng)配置。
@EnableAutoConfiguration 作為一個(gè)復(fù)合 Annotation,其自身定義關(guān)鍵信息如下:
@SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { ... }
其中,最關(guān)鍵的要屬 @Import(EnableAutoConfigurationImportSelector.class),借助 EnableAutoConfigurationImportSelector,@EnableAutoConfiguration 可以幫助 SpringBoot 應(yīng)用將所有符合條件的 @Configuration 配置都加載到當(dāng)前 SpringBoot 創(chuàng)建并使用的 IoC 容器。就像一只 “八爪魚” 一樣,借助于 Spring 框架原有的一個(gè)工具類:SpringFactoriesLoader 的支持,@EnableAutoConfiguration 可以智能的自動(dòng)配置功效才得以大功告成!
自動(dòng)配置幕后英雄:SpringFactoriesLoader 詳解
SpringFactoriesLoader 屬于 Spring 框架私有的一種擴(kuò)展方案,其主要功能就是從指定的配置文件 META-INF/spring.factories 加載配置。
public abstract class SpringFactoriesLoader { //... public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) { ... } public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { .... } }
配合 @EnableAutoConfiguration 使用的話,它更多是提供一種配置查找的功能支持,即根據(jù) @EnableAutoConfiguration 的完整類名 org.springframework.boot.autoconfigure.EnableAutoConfiguration 作為查找的 Key,獲取對應(yīng)的一組 @Configuration 類。
上圖就是從 SpringBoot 的 autoconfigure 依賴包中的 META-INF/spring.factories 配置文件中摘錄的一段內(nèi)容,可以很好地說明問題。
所以,@EnableAutoConfiguration 自動(dòng)配置的魔法騎士就變成了:從 classpath 中搜尋所有的 META-INF/spring.factories 配置文件,并將其中 org.springframework.boot.autoconfigure.EnableutoConfiguration 對應(yīng)的配置項(xiàng)通過反射(Java Refletion)實(shí)例化為對應(yīng)的標(biāo)注了 @Configuration 的 JavaConfig 形式的 IoC 容器配置類,然后匯總為一個(gè)并加載到 IoC 容器。
二、深入探索 SpringApplication 執(zhí)行流程
SpringApplication 的 run 方法的實(shí)現(xiàn)是我們本次旅程的主要線路,該方法的主要流程大體可以歸納如下:
1) 如果我們使用的是 SpringApplication 的靜態(tài) run 方法,那么,這個(gè)方法里面首先要?jiǎng)?chuàng)建一個(gè) SpringApplication 對象實(shí)例,然后調(diào)用這個(gè)創(chuàng)建好的 SpringApplication 的實(shí)例方法。在 SpringApplication 實(shí)例初始化的時(shí)候,它會(huì)提前做幾件事情:
- 根據(jù) classpath 里面是否存在某個(gè)特征類(org.springframework.web.context.ConfigurableWebApplicationContext)來決定是否應(yīng)該創(chuàng)建一個(gè)為 Web 應(yīng)用使用的 ApplicationContext 類型。
- 使用 SpringFactoriesLoader 在應(yīng)用的 classpath 中查找并加載所有可用的 ApplicationContextInitializer。
- 使用 SpringFactoriesLoader 在應(yīng)用的 classpath 中查找并加載所有可用的 ApplicationListener。
- 推斷并設(shè)置 main 方法的定義類。
2) SpringApplication 實(shí)例初始化完成并且完成設(shè)置后,就開始執(zhí)行 run 方法的邏輯了,方法執(zhí)行伊始,首先遍歷執(zhí)行所有通過 SpringFactoriesLoader 可以查找到并加載的 SpringApplicationRunListener。調(diào)用它們的 started() 方法,告訴這些 SpringApplicationRunListener,“嘿,SpringBoot 應(yīng)用要開始執(zhí)行咯!”。
3) 創(chuàng)建并配置當(dāng)前 Spring Boot 應(yīng)用將要使用的 Environment(包括配置要使用的 PropertySource 以及 Profile)。
4) 遍歷調(diào)用所有 SpringApplicationRunListener 的 environmentPrepared() 的方法,告訴他們:“當(dāng)前 SpringBoot 應(yīng)用使用的 Environment 準(zhǔn)備好了咯!”。
5) 如果 SpringApplication 的 showBanner 屬性被設(shè)置為 true,則打印 banner。
6) 根據(jù)用戶是否明確設(shè)置了 applicationContextClass 類型以及初始化階段的推斷結(jié)果,決定該為當(dāng)前 SpringBoot 應(yīng)用創(chuàng)建什么類型的 ApplicationContext 并創(chuàng)建完成,然后根據(jù)條件決定是否添加 ShutdownHook,決定是否使用自定義的 BeanNameGenerator,決定是否使用自定義的 ResourceLoader,當(dāng)然,最重要的,將之前準(zhǔn)備好的 Environment 設(shè)置給創(chuàng)建好的 ApplicationContext 使用。
7) ApplicationContext 創(chuàng)建好之后,SpringApplication 會(huì)再次借助 Spring-FactoriesLoader,查找并加載 classpath 中所有可用的 ApplicationContext-Initializer,然后遍歷調(diào)用這些 ApplicationContextInitializer 的 initialize(applicationContext)方法來對已經(jīng)創(chuàng)建好的 ApplicationContext 進(jìn)行進(jìn)一步的處理。
8) 遍歷調(diào)用所有 SpringApplicationRunListener 的 contextPrepared() 方法。
9) 最核心的一步,將之前通過 @EnableAutoConfiguration 獲取的所有配置以及其他形式的 IoC 容器配置加載到已經(jīng)準(zhǔn)備完畢的 ApplicationContext。
10) 遍歷調(diào)用所有 SpringApplicationRunListener 的 contextLoaded() 方法。
11) 調(diào)用 ApplicationContext 的 refresh() 方法,完成 IoC 容器可用的最后一道工序。
12) 查找當(dāng)前 ApplicationContext 中是否注冊有 CommandLineRunner,如果有,則遍歷執(zhí)行它們。
13) 正常情況下,遍歷執(zhí)行 SpringApplicationRunListener 的 finished() 方法、(如果整個(gè)過程出現(xiàn)異常,則依然調(diào)用所有 SpringApplicationRunListener 的 finished() 方法,只不過這種情況下會(huì)將異常信息一并傳入處理)
去除事件通知點(diǎn)后,整個(gè)流程如下:
本文以調(diào)試一個(gè)實(shí)際的 SpringBoot 啟動(dòng)程序?yàn)槔?,參考流程中主要類類圖,來分析其啟動(dòng)邏輯和自動(dòng)化配置原理。
總覽:
上圖為 SpringBoot 啟動(dòng)結(jié)構(gòu)圖,我們發(fā)現(xiàn)啟動(dòng)流程主要分為三個(gè)部分,第一部分進(jìn)行 SpringApplication 的初始化模塊,配置一些基本的環(huán)境變量、資源、構(gòu)造器、監(jiān)聽器,第二部分實(shí)現(xiàn)了應(yīng)用具體的啟動(dòng)方案,包括啟動(dòng)流程的監(jiān)聽模塊、加載配置環(huán)境模塊、及核心的創(chuàng)建上下文環(huán)境模塊,第三部分是自動(dòng)化配置模塊,該模塊作為 springboot 自動(dòng)配置核心,在后面的分析中會(huì)詳細(xì)討論。在下面的啟動(dòng)程序中我們會(huì)串聯(lián)起結(jié)構(gòu)中的主要功能。
啟動(dòng):
? 每個(gè) SpringBoot 程序都有一個(gè)主入口,也就是 main 方法,main 里面調(diào)用 SpringApplication.run() 啟動(dòng)整個(gè) spring-boot 程序,該方法所在類需要使用 @SpringBootApplication 注解,以及 @ImportResource 注解 (if need),@SpringBootApplication 包括三個(gè)注解,功能如下:
@EnableAutoConfiguration:SpringBoot 根據(jù)應(yīng)用所聲明的依賴來對 Spring 框架進(jìn)行自動(dòng)配置。
@SpringBootConfiguration(內(nèi)部為 @Configuration):被標(biāo)注的類等于在 spring 的 XML 配置文件中 (applicationContext.xml),裝配所有 bean 事務(wù),提供了一個(gè) spring 的上下文環(huán)境。
@ComponentScan:組件掃描,可自動(dòng)發(fā)現(xiàn)和裝配 Bean,默認(rèn)掃描 SpringApplication 的 run 方法里的 Booter.class 所在的包路徑下文件,所以最好將該啟動(dòng)類放到根包路徑下。
SpringBoot 啟動(dòng)類
首先進(jìn)入 run 方法
run 方法中去創(chuàng)建了一個(gè) SpringApplication 實(shí)例,在該構(gòu)造方法內(nèi),我們可以發(fā)現(xiàn)其調(diào)用了一個(gè)初始化的 initialize 方法
這里主要是為 SpringApplication 對象賦一些初值。構(gòu)造函數(shù)執(zhí)行完畢后,我們回到 run 方法
該方法中實(shí)現(xiàn)了如下幾個(gè)關(guān)鍵步驟:
- 創(chuàng)建了應(yīng)用的監(jiān)聽器 SpringApplicationRunListeners 并開始監(jiān)聽
- 加載 SpringBoot 配置環(huán)境 (ConfigurableEnvironment),如果是通過 web 容器發(fā)布,會(huì)加載 StandardEnvironment,其最終也是繼承了 ConfigurableEnvironment,類圖如下
可以看出,*Environment 最終都實(shí)現(xiàn)了 PropertyResolver 接口,我們平時(shí)通過 environment 對象獲取配置文件中指定 Key 對應(yīng)的 value 方法時(shí),就是調(diào)用了 propertyResolver 接口的 getProperty 方法
配置環(huán)境 (Environment) 加入到監(jiān)聽器對象中(SpringApplicationRunListeners)創(chuàng)建 run 方法的返回對象:ConfigurableApplicationContext(應(yīng)用配置上下文),我們可以看一下創(chuàng)建方法:
方法會(huì)先獲取顯式設(shè)置的應(yīng)用上下文 (applicationContextClass),如果不存在,再加載默認(rèn)的環(huán)境配置(通過是否是 web environment 判斷),默認(rèn)選擇 AnnotationConfigApplicationContext 注解上下文(通過掃描所有注解類來加載 bean),最后通過 BeanUtils 實(shí)例化上下文對象,并返回。
ConfigurableApplicationContext 類圖如下:
主要看其繼承的兩個(gè)方向:
LifeCycle:生命周期類,定義了 start 啟動(dòng)、stop 結(jié)束、isRunning 是否運(yùn)行中等生命周期空值方法
ApplicationContext:應(yīng)用上下文類,其主要繼承了 beanFactory(bean 的工廠類)
- 回到 run 方法內(nèi),prepareContext 方法將 listeners、environment、applicationArguments、banner 等重要組件與上下文對象關(guān)聯(lián)
- 接下來的 refreshContext(context)方法 (初始化方法如下) 將是實(shí)現(xiàn) spring-boot-starter-*(mybatis、redis 等)自動(dòng)化配置的關(guān)鍵,包括 spring.factories 的加載,bean 的實(shí)例化等核心工作。
? 配置結(jié)束后,Springboot 做了一些基本的收尾工作,返回了應(yīng)用環(huán)境上下文?;仡櫿w流程,Springboot 的啟動(dòng),主要?jiǎng)?chuàng)建了配置環(huán)境 (environment)、事件監(jiān)聽 (listeners)、應(yīng)用上下文 (applicationContext),并基于以上條件,在容器中開始實(shí)例化我們需要的 Bean,至此,通過 SpringBoot 啟動(dòng)的程序已經(jīng)構(gòu)造完成,接下來我們來探討自動(dòng)化配置是如何實(shí)現(xiàn)。
自動(dòng)化配置:
之前的啟動(dòng)結(jié)構(gòu)圖中,我們注意到無論是應(yīng)用初始化還是具體的執(zhí)行過程,都調(diào)用了 SpringBoot 自動(dòng)配置模塊。
SpringBoot 自動(dòng)配置模塊
該配置模塊的主要使用到了 SpringFactoriesLoader,即 Spring 工廠加載器,該對象提供了 loadFactoryNames 方法,入?yún)?factoryClass 和 classLoader,即需要傳入上圖中的工廠類名稱和對應(yīng)的類加載器,方法會(huì)根據(jù)指定的 classLoader,加載該類加器搜索路徑下的指定文件,即 spring.factories 文件,傳入的工廠類為接口,而文件中對應(yīng)的類則是接口的實(shí)現(xiàn)類,或最終作為實(shí)現(xiàn)類,所以文件中一般為如下圖這種一對多的類名集合,獲取到這些實(shí)現(xiàn)類的類名后,loadFactoryNames 方法返回類名集合,方法調(diào)用方得到這些集合后,再通過反射獲取這些類的類對象、構(gòu)造方法,最終生成實(shí)例。
工廠接口與其若干實(shí)現(xiàn)類接口名稱
下圖有助于我們形象理解自動(dòng)配置流程。
SpringBoot 自動(dòng)化配置關(guān)鍵組件關(guān)系圖
mybatis-spring-boot-starter、spring-boot-starter-web 等組件的 META-INF 文件下均含有 spring.factories 文件,自動(dòng)配置模塊中,SpringFactoriesLoader 收集到文件中的類全名并返回一個(gè)類全名的數(shù)組,返回的類全名通過反射被實(shí)例化,就形成了具體的工廠實(shí)例,工廠實(shí)例來生成組件具體需要的 bean。
之前我們提到了 EnableAutoConfiguration 注解,其類圖如下:
可以發(fā)現(xiàn)其最終實(shí)現(xiàn)了 ImportSelector(選擇器) 和 BeanClassLoaderAware(bean 類加載器中間件),重點(diǎn)關(guān)注一下 AutoConfigurationImportSelector 的 selectImports 方法。
該方法在 springboot 啟動(dòng)流程——bean 實(shí)例化前被執(zhí)行,返回要實(shí)例化的類信息列表。我們知道,如果獲取到類信息,spring 自然可以通過類加載器將類加載到 jvm 中,現(xiàn)在我們已經(jīng)通過 spring-boot 的 starter 依賴方式依賴了我們需要的組件,那么這些組建的類信息在 select 方法中也是可以被獲取到的,不要急我們繼續(xù)向下分析。
該方法中的 getCandidateConfigurations 方法,通過方法注釋了解到,其返回一個(gè)自動(dòng)配置類的類名列表,方法調(diào)用了 loadFactoryNames 方法,查看該方法
在上面的代碼可以看到自動(dòng)配置器會(huì)根據(jù)傳入的 factoryClass.getName() 到項(xiàng)目系統(tǒng)路徑下所有的 spring.factories 文件中找到相應(yīng)的 key,從而加載里面的類。我們就選取這個(gè) mybatis-spring-boot-autoconfigure 下的 spring.factories 文件
進(jìn)入 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 中,主要看一下類頭:
發(fā)現(xiàn) Spring 的 @Configuration,儼然是一個(gè)通過注解標(biāo)注的 springBean,繼續(xù)向下看,
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class}) 這個(gè)注解的意思是:當(dāng)存在 SqlSessionFactory.class, SqlSessionFactoryBean.class 這兩個(gè)類時(shí)才解析 MybatisAutoConfiguration 配置類,否則不解析這一個(gè)配置類,make sence,我們需要 mybatis 為我們返回會(huì)話對象,就必須有會(huì)話工廠相關(guān)類。
@CondtionalOnBean(DataSource.class):只有處理已經(jīng)被聲明為 bean 的 dataSource。
@ConditionalOnMissingBean(MapperFactoryBean.class) 這個(gè)注解的意思是如果容器中不存在 name 指定的 bean 則創(chuàng)建 bean 注入,否則不執(zhí)行(該類源碼較長,篇幅限制不全粘貼)
? 以上配置可以保證 sqlSessionFactory、sqlSessionTemplate、dataSource 等 mybatis 所需的組件均可被自動(dòng)配置,@Configuration 注解已經(jīng)提供了 Spring 的上下文環(huán)境,所以以上組件的配置方式與 Spring 啟動(dòng)時(shí)通過 mybatis.xml 文件進(jìn)行配置起到一個(gè)效果。通過分析我們可以發(fā)現(xiàn),只要一個(gè)基于 SpringBoot 項(xiàng)目的類路徑下存在 SqlSessionFactory.class, SqlSessionFactoryBean.class,并且容器中已經(jīng)注冊了 dataSourceBean,就可以觸發(fā)自動(dòng)化配置,意思說我們只要在 maven 的項(xiàng)目中加入了 mybatis 所需要的若干依賴,就可以觸發(fā)自動(dòng)配置,但引入 mybatis 原生依賴的話,每集成一個(gè)功能都要去修改其自動(dòng)化配置類,那就得不到開箱即用的效果了。所以 Spring-boot 為我們提供了統(tǒng)一的 starter 可以直接配置好相關(guān)的類,觸發(fā)自動(dòng)配置所需的依賴 (mybatis) 如下:
這里是截取的 mybatis-spring-boot-starter 的源碼中 pom.xml 文件中所有依賴:
因?yàn)?maven 依賴的傳遞性,我們只要依賴 starter 就可以依賴到所有需要自動(dòng)配置的類,實(shí)現(xiàn)開箱即用的功能。也體現(xiàn)出 Springboot 簡化了 Spring 框架帶來的大量 XML 配置以及復(fù)雜的依賴管理,讓開發(fā)人員可以更加關(guān)注業(yè)務(wù)邏輯的開發(fā)。
總結(jié)
到此這篇關(guān)于SpringBoot啟動(dòng)原理的文章就介紹到這了,更多相關(guān)SpringBoot啟動(dòng)原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot整合EasyExcel進(jìn)行大數(shù)據(jù)處理的方法詳解
EasyExcel是一個(gè)基于Java的簡單、省內(nèi)存的讀寫Excel的開源項(xiàng)目。在盡可能節(jié)約內(nèi)存的情況下支持讀寫百M(fèi)的Excel。本文將在SpringBoot中整合EasyExcel進(jìn)行大數(shù)據(jù)處理,感興趣的可以了解一下2022-05-05java8實(shí)現(xiàn)list集合中按照某一個(gè)值相加求和,平均值等操作代碼
這篇文章主要介紹了java8實(shí)現(xiàn)list集合中按照某一個(gè)值相加求和,平均值等操作代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08MyBatis Plus 實(shí)現(xiàn)多表分頁查詢功能的示例代碼
這篇文章主要介紹了MyBatis Plus 實(shí)現(xiàn)多表分頁查詢功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08SpringBoot+MyBatis+Redis實(shí)現(xiàn)分布式緩存
本文主要介紹了SpringBoot+MyBatis+Redis實(shí)現(xiàn)分布式緩存,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01JavaWeb實(shí)現(xiàn)同一帳號同一時(shí)間只能一個(gè)地點(diǎn)登陸(類似QQ登錄的功能)
最近做了企業(yè)項(xiàng)目,其中有這樣的需求要求同一帳號同一時(shí)間只能一個(gè)地點(diǎn)登陸類似QQ登錄的功能。下面小編通過本文給大家分享實(shí)現(xiàn)思路,感興趣的朋友參考下吧2016-11-11SpringBoot JPA實(shí)現(xiàn)增刪改查、分頁、排序、事務(wù)操作等功能示例
本篇文章主要介紹了SpringBoot JPA實(shí)現(xiàn)增刪改查、分頁、排序、事務(wù)操作等功能示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03