javascript
SpringBoot源码分析(二)之自动装配demo
SpringBoot源碼分析(二)之自動裝配demo
文章目錄
- SpringBoot源碼分析(二)之自動裝配demo
- 前言
- 一、創(chuàng)建RedissonTemplate的Maven服務(wù)
- 二、創(chuàng)建測試服務(wù)
- 三、總結(jié)
前言
Spring Framework一致在解決如何讓bean的管理更加簡單,如何讓開發(fā)者盡可能少的去管理bean生成的一些配置;當我們在引用其他模塊中的bean時,我們可以自動的創(chuàng)建bean,并交給spring的Ioc容器去管理。
spring3.x產(chǎn)生了Enable模塊驅(qū)動注解,在調(diào)用其他模塊bean的時候,可以通過Enable注解或者import注解生成bean。但是在spring4.x中,conditional條件注解的出現(xiàn)才真正的實現(xiàn)了自動裝配。
在閱讀自動裝配源碼之前,我們先來演示一個自動裝配的案例。本文講解的是如何定義一個有條件的Redis自動裝配的模板。
一、創(chuàng)建RedissonTemplate的Maven服務(wù)
Maven項目版本:
<groupId>com.my</groupId> <artifactId>RedissonTemplate</artifactId> <version>1.0-SNAPSHOT</version>創(chuàng)建帶有@Configuration注解的RedissonAutoConfiguration.class:
package com.my.redission;import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@EnableConfigurationProperties(RedissonProperties.class) @Configuration //@ConditionalOnClass(RedissonProperties.class) public class RedissonAutoConfiguration {/*** RedissonClient:操作Redis的核心對象* 將該對象注入到容器中* 需要連接Redis 服務(wù), host port* @return*/@Beanpublic RedissonClient redissonClient(RedissonProperties redissonProperties){Config config = new Config();String prefix = "redis://";if(redissonProperties.getSsl()){prefix = "rediss://";}config.useSingleServer().setAddress(prefix+redissonProperties.getHost()+":"+redissonProperties.getPort()).setTimeout(redissonProperties.getTimeout());return Redisson.create(config);}}我們可以看到改類上攜帶了EnableConfigurationProperties(RedissonProperties.class)注解,該注解是自動從application.yml/application.properties文件中獲取關(guān)于Redis的有關(guān)配置參數(shù)。
RedissonProperties.clas
此處使用了lombok.Data注解,就不需要我們對RedissonProperties的成員變量進行g(shù)et、set處理了。但是別忘記了需要添加lombok.Data的依賴。
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency>此刻,我們完成了程序的編寫,接下來,我們會配置我們服務(wù)的自動裝配。
我們需要在resource下創(chuàng)建一個META-INF文件夾,在META-INF文件夾下添加三個文件,分別是:spring.factories、additional-spring-configuration-metadata.json和spring-autoconfigure-metadata.properties。
首先,我們先講一下additional-spring-configuration-metadata.json,該文件是為了配置如何從application.yml/application.properties文件中獲取RedissonProperties中的成員變量的信息,也就是Redis的配置參數(shù)。
additional-spring-configuration-metadata.json
spring.factories文件中配置了RedissonAutoConfiguration類的全路徑,可以讓Spring Boot通過自動裝配加載RedissonAutoConfiguration類。加載的原理是通過SpringFactoriesLoader從classpath/META-INF/spring.factories文件中,根據(jù)key來加載對應(yīng)的類到spring IoC容器中。該文件中的數(shù)據(jù)格式:key為自定配置類EnableAutoConfiguration的全路徑,value是配置類的全路徑;其中EnableAutoConfiguration就是自動裝配的Enable。
spring.factories
Spring Boot的自動裝配中可以使用條件過濾,即conditional。
AutoConfigurationImportSelector方法會先掃描spring-autoconfiguration-metadata.properties文件,獲取需要裝配的類;最后再掃描spring.factories對應(yīng)的類時,會結(jié)合前面的元數(shù)據(jù)進行過濾。為什么自動裝配需要有過濾的條件,因為@Configuration注釋的bean大部分情況下,需要依賴其他框架的類,當依賴的類不存在時,就不能將該bean注入到Ioc。同時也可以減少無效的@configuration類的數(shù)量從而降低SpringBoot的啟動時間。Spring Boot同時也將自己的二方依賴框架和友商的依賴框架的@Configuration的類全路徑添加在spring-boot、spring-boot-autoconfigure框架下的classpath/META-INF/spring.factories文件中,當條件滿足的時候,會自動加載spring.factories文件中的bean。
就像本文的demo,RedissonTemplate在創(chuàng)建RedissonAutoConfiguration類時,需要依賴org.redisson.api.RedissonClient類。那么我們就可以將這個條件加上,只有當項目的classpath中有org.redisson.api.RedissonClient類時,Spring Boot的自動裝配才能將RedissonAutoConfiguration加載到Ioc中。
spring-autoconfigure-metadata.properties
ConditionalOnClass的意思就是后面的類需要存在,同時Conditional條件注解還有很多。像:ConditionalOnBean、ConditionalOnResource等。
如果我們不使用spring-autoconfigure-metadata.properties文件配置,也可以在RedissonAutoConfiguration類上添加@ConditionalOnClass(RedissonProperties.class)注解。
至此,我們的RedissonTemplate配置完成。
二、創(chuàng)建測試服務(wù)
首先我們先創(chuàng)建一個spring boot項目,將RedissonTemplate的依賴引入。
<dependency><groupId>com.my</groupId><artifactId>RedissonTemplate</artifactId><version>1.0-SNAPSHOT</version> </dependency>然后在application.yml/application.properties文件中配置Redis的啟動參數(shù):
my:redisson:host: 127.0.0.1port: 6379timeout: 2000編寫測試案例,我們通過Controller對外提供一個get接口,在瀏覽器中通過訪問get接口來訪問Redis中的數(shù)據(jù),如果能正常連接到Redis并正常訪問Redis數(shù)據(jù),及代表,RedissonTemplate被自動裝配到Ioc中。
首先,我們先排除@ComponentScan注解的自動掃描。由圖可以看出,我們沒有配置@ComponentScan掃描路徑,所以該路徑為當前class路徑及其子類。
我們的啟動類的全路徑:com.example.demo1.Demo1Application
我們的RedissonTemplate的全路徑:com.my.redission.RedissonAutoConfiguration
編寫我們的Controller層代碼:
package com.example.demo1.action;import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/api") public class RedissionAction {@Autowiredprivate RedissonClient redissonClient;@GetMapping("/query")public String query(){return "key的個數(shù)="+redissonClient.getKeys().count()+"";} }由1中可以得知,自動裝配RedissonTemplate的條件是
我們看一下我們的libraries中是否存在org.redission框架,以及該框架中是否存在RedisClient。
可以看出,我們的條件滿足自動裝配RedissonTemplate。接下來,我們運行Spring Boot測試項目。可以看到啟動日志中打印出連接上Redis的日志信息。
同時,我們來訪問我們的controller接口,可以看到返回了redis中的key的數(shù)量。
接下來,我們測試一下條件不符合的場景。
我們將spring-autoconfigure-metadata.properties文件的條件改成:項目中必須存在rg.redisson.api.RedissonClientTets類,當然了該類是不存在的。
此時,我們再運行測試項目,將會看到Spring Boot啟動報錯,顯示Field redissonClient in com.example.demo1.action.RedissionAction required a bean of type ‘org.redisson.api.RedissonClient’ that could not be found.
意思就是找不到RedissonClient這個Bean。
三、總結(jié)
至此,我們完成了如何配置一個自動裝配的工程。下一章節(jié),我們將從源碼的角度去解讀自動裝配的邏輯。
總結(jié)
以上是生活随笔為你收集整理的SpringBoot源码分析(二)之自动装配demo的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【微信小程序】引用echarts 在真机
- 下一篇: 黑客为“炫技”随机攻击,结果被“顺着网线