SpringBoot2自動裝配原理解析
1、SpringBoot特點
1.1 依賴管理
父項目做依賴管理
springboot項目的父項目 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> </parent> spring-boot-starter-parent的父項目 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.3.4.RELEASE</version> </parent>
父項目整合了所有開發(fā)中常用的依賴的版本號,稱為自動版本仲裁機制。
注意:這不是說無需導入依賴了,而是指在導入依賴的時候,會自動仲裁(匹配)版本號,相當于模具的功能。
開發(fā)導入starter場景啟動器
場景啟動器的功能是:springboot已經(jīng)幫我們整合了所有應用場景常規(guī)的依賴,只要依賴中寫入某場景啟動器,之下的所有依賴也都一一導入了。
- 官方整合的場景啟動器一般是:spring-boot-starter-*。
- 只要引入starter,這個場景的所有常規(guī)需要的依賴都會自動引入。
- SpringBoot所有支持的場景都在:https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter 這個地址里。
- 第三方提供的簡化開發(fā)的場景啟動器一般是:*-spring-boot-starter
- 所有場景啟動器都有一個最底層的依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.3.4.RELEASE</version> <scope>compile</scope> </dependency>
自動版本仲裁機制
意味著無需關注版本號,即導即用。
注意:
引入父項目中已經(jīng)整合過的依賴,都可以不寫版本號。
但引入沒有版本仲裁的jar,需要寫版本號。
如果對整合過的依賴的版本號不滿意,可以修改默認的版本號,方法如下:
1、查看spring-boot-dependencies里面規(guī)定當前依賴的版本 用的 key。 2、在當前項目里面重寫配置,如: <properties> <mysql.version>5.1.43</mysql.version> </properties>
1.2 自動配置
springboot已經(jīng)配置好了那些繁文縟節(jié)的配置文件,不用我們額外的配置
比如:
1、Tomcat
2、SpringMVC(引入了全套組件、常用的功能)DispathcherServlet等
3、Web常見功能:字節(jié)編碼,內(nèi)部視圖解析器
4、默認的掃描包結構
- 之前我們在方法上加注釋,需要在配置文件中掃描包名等,現(xiàn)在已經(jīng)不需要了。
- 主程序Application所在包及其子包里面的組件都會被默認掃描進來
- 如果想要改變掃描路徑,可以在主程序上的springboot聲明注解中設置scanBasePackages屬性
@SpringBootApplication(scanBasePackages="com.atguigu")
public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class,args); } }
5、各種配置擁有默認值
如果需要更改默認值,可以在resource文件下創(chuàng)建application.properties,修改其中的默認值
默認配置的原理:
- 默認配置最終都是映射到某個類上,如:MultipartProperties
- 配置文件的值最終會綁定每個類上,這個類會在容器中創(chuàng)建對象
- 引入了哪些場景這個場景的自動配置才會開啟
- SpringBoot所有的自動配置功能都在spring-boot-autoconfigure包里面
2、容器功能
2.1 組件添加
1、@Configuration
/** * 1、配置類里面使用@Bean標注在方法上給容器注冊組件,默認也是單實例的 * 2、配置類本身也是組件 * 3、proxyBeanMethods = true 默認是true 表示代理bean的方法 (動態(tài)代理) * Full模式(proxyBeanMethods = true) * Lite模式(proxyBeanMethods = false) * 組件依賴 */ @Configuration(proxyBeanMethods = true) //告訴SpringBoot這是一個配置類 == xml配置文件 public class MyConfig { /** * 外部無論對配置類中的這個組件注冊方法調(diào)用多少次獲取的都是之前注冊容器中的單實例對象 * @return */ //給容器中添加組件,相當于bean標簽,以方法名作為組件的id。 返回類型是組件類型,返回值就是組件在容器中的實例。 @Bean public User user01(){ return new User("zhangsan",18); } // 如果不想用方法名作為組件的id 可以修改Bean中的value屬性,自定義組件id @Bean("tom") //此時組件id就不再是tomcatPet,而是tom public Pet tomcatPet(){ return new Pet("tomcat"); }
Full模式和Lite模式(新版本增加)
配置 類組件之間無依賴關系用Lite模式加速容器啟動過程,減少判斷
配置類組件之間有依賴關系,方法會被調(diào)用得到之前單實例組件,用Full模式
2、@Bean、@Component、@Controller、@Service、@Repository
這些注解與Spring中學習的作用一致,不再解釋。
3、@ComponentScan、@Import
ComponentScan是組件掃描的意思。
@Import()
Import注解后面填的是類的數(shù)組,作用是給容器中自動創(chuàng)建出這兩個類型的組件、且默認組件的名字是全包名。
(可以與@Bean方法創(chuàng)建出的組件是方法名相對比)。
4、@Conditional
條件裝配
@ConditionalOnBean(name = "tom")
此注釋表示:只有在IOC容器中有tom名稱的類才將這個注釋掛載的類/方法注冊。
2.2、原生配置引入@ImportResource
在一些老的項目或者第三方包引入的時候,很可能還是采用老版的xml方式注冊組件,可以在任一配置類上加上此注解,導入xml的地址就可以引入。
使用方式:
1、首先創(chuàng)建xml配置文件,寫入一個bean
<bean id="user02" class="com.atguigu.boot.bean.User"> <property name="age" value="20"/> <property name="name" value="xcc"/> </bean>
2、在任意一個配置類上加上@ImportResource注解
@ImportResource("classpath:beans.xml") public class MyConfig { }
2.3 配置綁定
1、@ConfigurationProperties
一些需要抽離的會改變的配置,之前會以properties文件的形式存儲,然后通過讀取文件,來放入javabean中,但是該注解不必如此麻煩。
只要將需要配置的類加入容器中,再使用@ConfigurationProperties注解,就能夠自動將applicaton.properties文件中的屬性注入該類。
使用步驟:
1、創(chuàng)建實體類,然后加上@Component注解,將該類注冊進容器中。
2、使用@ConfigurationProperties注解,prefix的含義是,所有mycar開頭的屬性就是要注入的配置內(nèi)容。
/** * 只有在容器中的組件,才會擁有springboot的強大功能 */ @Component @ConfigurationProperties(prefix = "mycar") public class Car { //一些屬性get、set方法云云 }
3、在application.properties中配置需要注入的屬性
mycar.brand = BYD mycar.price = 100000
注意:如果該類是引入包里的類,不方便直接在要注入的類上加注釋
可以在配置文件中如此聲明
@EnableConfigurationProperties(Car.class)
該注釋的作用有2個:
1、開啟配置綁定功能。
2、把組件自動注冊到容器中。
3、自動配置原理入門
3.1 引導加載自動配置類
為什么springboot可以不用我們使用xml文件(僅使用Bean)就可以向容器中注冊組件?
原因在于springboot主程序下的聲明注解:
@SpringBootApplication
該注解由3個注解復合而成:
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootConfiguration:
這個注解其實就是一個Configuration注解,聲明主程序也是一個特殊的配置類。
@ComponentScan
這個注解起到了掃描包的作用,指定掃描包的路徑
@EnableAutoConfiguration
@AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {}
1、@AutoConfigurationPackage
自動配置包,點進去可以看到:
@Import(AutoConfigurationPackages.Registrar.class) //給容器中導入一個組件 public @interface AutoConfigurationPackage {} //利用Registrar給容器中導入一系列組件 //將指定的一個包下的所有組件導入進來?MainApplication 所在包下。
首先Import導入了一個組件,然后這個組件的功能是用來注冊掃描的包下所有的組件。
2、@Import(AutoConfigurationImportSelector.class)
有選擇的自動配置一些組件。
1、利用getAutoConfigurationEntry(annotationMetadata);給容器中批量導入一些組件
2、調(diào)用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)獲取到所有需要導入到容器中的配置類
3、利用工廠加載 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的組件
4、從META-INF/spring.factories位置來加載一個文件。
默認掃描我們當前系統(tǒng)里面所有META-INF/spring.factories位置的文件
spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
總的來說:springboot將所有環(huán)境的配置全部寫在了一個一個工廠的配置文件里。
3.2 按需開啟自動匹配項
127個場景的所有自動配置啟動的時候默認全部加載。xxxxAutoConfiguration
原理:按照條件裝配規(guī)則(@Conditional),將選擇的配置加載。
3.3 修改默認配置
@Bean @ConditionalOnBean(MultipartResolver.class) //容器中有這個類型組件 @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中沒有這個名字 multipartResolver 的組件 public MultipartResolver multipartResolver(MultipartResolver resolver) { //給@Bean標注的方法傳入了對象參數(shù),這個參數(shù)的值就會從容器中找。 //SpringMVC multipartResolver。防止有些用戶配置的文件上傳解析器不符合規(guī)范 // Detect if the user has created a MultipartResolver but named it incorrectly return resolver; }
給容器中加入了文件上傳解析器;
springboot幫我們底層封裝了一個注解方法,將不符合規(guī)范的命名也更正了。
SpringBoot默認會在底層配好所有的組件。但是如果用戶自己配置了以用戶的優(yōu)先。
*******總結********:
- SpringBoot先加載所有的自動配置類 xxxxxAutoConfiguration
- 每個自動配置類按照條件進行生效,默認都會綁定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件進行了綁定
- 生效的配置類就會給容器中裝配很多組件
- 只要容器中有這些組件,相當于這些功能就有了
- 定制化配置
- 用戶直接自己@Bean替換底層的組件
- 用戶去看這個組件是獲取的配置文件什么值就去修改。
xxxxxAutoConfiguration ---> 組件 ---> xxxxProperties里面拿值 ----> application.properties
3.4 配置流程
- 引入場景依賴
- https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
- 查看自動配置了哪些(選做)
- 自己分析,引入場景對應的自動配置一般都生效了
- 配置文件中debug=true開啟自動配置報告。Negative(不生效)\Positive(生效)
- 是否需要修改
- 參照文檔修改配置項
- https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties
- 自己分析。xxxxProperties綁定了配置文件的哪些。
- 自定義加入或者替換組件
- @Bean、@Component。。。
- 自定義器 XXXXXCustomizer;
- .....
4、開發(fā)工具
4.1 lombok
lombok可以簡化javabean的編寫。
當我們創(chuàng)建javabean類的時候,總要編寫其getset方法,toString方法、有參無參構造器,很煩而且代碼很多不清晰。
可以加lombok注解簡化編寫。
使用前提:
1、添加lombok的依賴。
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
2、在插件市場安裝lombok插件。
使用說明:
@ToString @Data @NoArgsConstructor @AllArgsConstructor public class Pet { private String name; }
@Data:自動編寫其get/set方法。
@ToString:自動重寫其toString方法。
@NoArgsConstructor:編寫無參構造器。
@AllArgsConstructor:編寫有參構造器。需要注意的是,有參構造器默認是將所有的參數(shù)都構造,如果要想限定個數(shù)個參數(shù)構造,還是需要自己寫。
@Slf4j:日志注解??梢酝ㄟ^log.info在控制臺打印消息。
4.2 dev-tools
熱更新,在修改了方法或頁面時,只需要用dev-tools(Ctrl+F9)就行重新編譯,速度要比重啟項目快一些
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
4.3 Spring Initailizr(項目初始化向?qū)В?/h3>
在創(chuàng)建項目的時候,只需要勾選環(huán)境,就會自動幫我們搭建項目所需要的環(huán)境。
所以我們只需要關注項目本身的代碼。
到此這篇關于SpringBoot2自動裝配原理的文章就介紹到這了,更多相關SpringBoot2自動裝配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Springboot視頻接口報大量的ClientAbortException找不到原因的解決
本文主要介紹了Springboot視頻接口報大量的ClientAbortException找不到原因的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-08-08MyBatis簡介與配置MyBatis+Spring+MySql的方法
MyBatis 是一個可以自定義SQL、存儲過程和高級映射的持久層框架。這篇文章主要介紹了MyBatis簡介與配置MyBatis+Spring+MySql的方法,需要的朋友可以參考下2017-04-04Java實現(xiàn)CORS跨域請求的實現(xiàn)方法
本篇文章主要介紹了Java實現(xiàn)CORS跨域請求的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09Java listener簡介_動力節(jié)點Java學院整理
這篇文章主要介紹了Java listener簡介,可以用于統(tǒng)計用戶在線人數(shù)等,有興趣的可以了解一下2017-07-07Java中JSON字符串進行各種轉(zhuǎn)換的方法小結
Gson和Hutool的JSONUtil都是常用的用于處理JSON數(shù)據(jù)的工具庫,它們提供了簡單易用的API來進行JSON字符串的解析、轉(zhuǎn)換和操作,下面就跟隨小編一起學習一下如果使用他們實現(xiàn)JSON字符串的各種轉(zhuǎn)換吧2024-01-01