文章挺長,表達不好,希望能有獲~~~~~~~
Spring也提供使用註解來註冊bean,為什麼要用SpringBoot呢?
使用Spring應用,比如SpringMVC還行需要配置ViewResolver、DispatcherServlet,使用Mybatis等也需要進行其他配置。
如下為spring-mybatis配置檔案:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 匯入屬性配置檔案 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
</bean>
<!-- 將資料來源對映到sqlSessionFactory中 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
<property name="dataSource" ref="dataSource" />
<!--<property name="mapperLocations" value="classpath:mybatis/mapper/*.xml" />-->
</bean>
<!-- SqlSession模板類例項 -->
<bean id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="close">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<!--======= 事務配置 Begin ================= -->
<!-- 事務管理器(由Spring管理MyBatis的事務) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 關聯資料來源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--======= 事務配置 End =================== -->
<!--mapper配置-->
<bean id="kbCityMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.spring.dao.KbCityMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
</beans>
SpringBoot進行自動配置不在需用使用者進行這些配置。而且使用SpringBoot也不需要管理Mybatis、log4j、jackson等依賴包的版本問題,SpringBoot使用starter進行依賴管理。
使用SpringBoot只需在application.yml
或application.xml
新增少量配置,通過@SpringBootApplication
即可啟動應用。
自動裝配的意義在於SpringBoot提前為我們初始化了一些東西,從SpringBoot文件中搜尋Auto-configuration
對於JSON mapping libraries:
對於Spring MVC:
可以看到有對BeanNameViewResolver
的自動配置。
對於模板引擎:
可以看到對Thymeleaf
的自動配置,我們只需要引入Thymeleaf依賴就能直接用了,不需要任何配置。
對Reids:
還有對Security,Spring Data JPA,Elasticsearch等等很多很多,SpringBoot都對他們提前進行了一些配置,這樣使得我們只需引入其依賴,只需要在application.yml
少量配置甚至不需要配置就可以直接使用。
那麼SpringBoot是怎麼實現的?
文件說讓我們瀏覽spring-boot-autoconfigure
的原始碼,那麼我們就看看原始碼:
先說一下META-INF包下的,我們看一看additional-spring-configuration-metadata.json
這個檔案裡有啥呢?
我們看一看其中server.port
:
嗯,他預設值是8080,是不是很熟悉呢?我們進入我們專案的application.properties
那麼我們再看看server.servlet.encoding.enabled
,server.servlet.jsp.class-name
這兩個
這回我們知道原來application.properties
中的預設值是從additional-spring-configuration-metadata.json
這個檔案來的呀。
接下來看看spring.factories
檔案:
裡面都是一些AutoConfiguration
類的完整類路徑,那麼我們有了類路徑能幹啥呢?那當然通過反射建立該類了。那麼有這麼多自動配置類肯定不會全部載入,那些我們要用到SpringBoot就載入哪些。
spring-autoconfigure-metadata.properties
:看其內容,等號左邊為類路徑或屬性,右邊或者類路徑或者值或者空。應該跟我們平常的properties檔案一樣的意思吧,為了不將這些配置屬性在程式碼中寫死,將其提取出來放到properties檔案中。
spring-autoconfigure-metadata.json
:只知道name與sourceType,type,sourceMethod建立對映關係,不知道幹啥用。或許為了通過name標識值在程式碼中更清晰易懂吧。
繼續向下看:
這裡面可以看到很多熟悉的名字,我們以web包為例看一看吧:
這些類大致分為兩種,一種AutoConfiguration
,一種Properties
。
題外話:我們知道SpringBoot掃描靜態資源時會在/resources/, /static/, /public/這些路徑下。我們看看WebProperties.java
接著我們以WebMvcProperties
和WebMvcAutoConfiguration
為例看一看吧。
WebMvcProperties
:就在這個屬性類中完成了webMvc相關屬性的初始化工作。
某些屬性如下:
private String staticPathPattern = "/**";
public static class Servlet {
/**
* Path of the dispatcher servlet. Setting a custom value for this property is not
* compatible with the PathPatternParser matching strategy.
*/
private String path = "/";
public String getServletMapping() {
if (this.path.equals("") || this.path.equals("/")) {
return "/";
}
if (this.path.endsWith("/")) {
return this.path + "*";
}
return this.path + "/*";
}
}
WebMvcAutoConfiguration
:這個類就通過get方法,從上面的properties檔案中取值,有了這些屬性值,那麼就能完成webMvc相關類的初始化工作了!!!
接下來從springbootApplication註解,進入來看看吧。
@SpringBootConfiguration
:進去看後是一個@Configuration
,因此SpringBootConfiguration註解的作用是將其註解的類註冊到spring中。
@ComponentScan
:元件掃描類,在此包下的被controller,service,component等註解類註冊到spring中。
@EnableAutoConfiguration
:以下主要分析。
檢視@AutoConfigurationPackage
:
進入AutoConfigurationPackages.Registrar.class
:
debug一下registerBeanDefinitions
方法:
通過上面的gif我們可以看到registerBeanDefinitions
這個方法應該就是註冊我們自己包下所有bean。
接著進入AutoConfigurationImportSelector.class
:
進入getAutoConfigurationEntry
->getCandidateConfigurations
->loadFactoryNames
->loadSpringFactories
這裡會獲取到spring.factories檔案,然後載入他,然後迴圈遍歷將其放入result中。
我們debug進入時:
result為一個map,我們以org.springframework.boot.autoconfigure.EnableAutoConfiguration
為key,取出那size為130的List<String>
。
現在我們從getCandidateConfigurations
出來了,configuration
的size大小130,然後去重,排除。
在執行getConfigurationClassFilter().filter(configurations);
方法前configurations
的size還為130。
執行之後:
最終我們載入了這23個配置類。
如何建立自己的starter:
demo project我看了,六年前更新的,使用的springboot1,很老的版本了。這個示例的pom的依賴引入的很繁雜,可以看看人家寫的自動配置類,挺齊全的。
三個點:
- pom檔案引入springboot依賴(我看guide哥的部落格,直接引入這個依賴就能用了。)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.5</version>
<scope>compile</scope>
</dependency>
- 建立自動配置類,其上有必須
@Configuration
,其他約束性註解根據情況新增 - 將這個自動配置類寫到,spring.factories檔案
終於完結。
?