Java使用@EnableEurekaServer實(shí)現(xiàn)自動(dòng)裝配詳解
實(shí)踐
仿照@EnableEurekaServer實(shí)現(xiàn)自動(dòng)裝配
如果你使用過(guò)Eureka作為微服務(wù)的注冊(cè)中心,那么對(duì)@EnableWebConfigure一定很了解,該注解用來(lái)開啟Eureka服務(wù)端作為微服務(wù)的注冊(cè)中心,其背后是springboot自動(dòng)裝配原理。
本次,將仿照此設(shè)計(jì)思路,完成Web應(yīng)用統(tǒng)一異常處理、TraceId鏈路日志追蹤、Json序列化消息處理器等通用能力的自動(dòng)裝配。
@EnableEurekaServer
通過(guò)源碼我們得知,此注解的源碼如下
/** * Annotation to activate Eureka Server related configuration. * {@link EurekaServerAutoConfiguration} * * @author Dave Syer * @author Biju Kunjummen * */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(EurekaServerMarkerConfiguration.class) public @interface EnableEurekaServer { }
那么,如何通過(guò)在啟動(dòng)類標(biāo)識(shí)此注解即可實(shí)現(xiàn)EurekaServer的自動(dòng)裝配呢?
答案其實(shí)在這一句
@Import(EurekaServerMarkerConfiguration.class)
該注解使用了@Import注解導(dǎo)入了一個(gè)配置類 EurekaServerMarkerConfiguration.java,該配置類源碼如下
@Configuration(proxyBeanMethods = false) public class EurekaServerMarkerConfiguration { @Bean public Marker eurekaServerMarkerBean() { return new Marker(); } class Marker { } }
我們看到,該配置類聲明了一個(gè)Bean 內(nèi)部類Marker
那么,為什么聲明這個(gè)類?這個(gè)類看起來(lái)沒(méi)有任何屬性和方法
我們?cè)趯?dǎo)入的EurekaServer包中繼續(xù)尋找答案
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
通過(guò)Command + 單擊 Marker類,我們看到了如下引用
@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
可以發(fā)現(xiàn),一個(gè)條件裝配使用了這個(gè)類,該注解的含義是當(dāng)上下文中有Marker實(shí)例時(shí),進(jìn)行注解所在配置類的裝配,也就是 EurekaServerAutoConfiguration
通過(guò)查看其源碼,可以看到大量的EurekaServer相關(guān)Bean聲明,也就是說(shuō),實(shí)現(xiàn)了EurekaServerAutoConfiguration的裝配,也就實(shí)現(xiàn)類EurekaServer的裝配
好的,思路清晰了 通過(guò)@EnableEurekaServer來(lái)導(dǎo)入EurekaServerMarkerConfiguration,進(jìn)而將內(nèi)部類Marker實(shí)例化到spring上下文中,通過(guò)條件裝配,再來(lái)裝配EurekaServerAutoConfiguration配置文件
也就是說(shuō) 內(nèi)部類Marker 起到了一個(gè)開關(guān)的作用
接下來(lái)只剩最后一個(gè)問(wèn)題,我們只寫了一行代碼,也就是 @EnableEurekaServer 加到了springboot啟動(dòng)類上,那么 EurekaServerAutoConfiguration 是怎樣被識(shí)別并導(dǎo)入到我們自己的項(xiàng)目中呢?
涉及到另一個(gè)知識(shí)點(diǎn) spring.factories 它可以實(shí)現(xiàn),將我們編寫的jar包中的配置類,能夠被依賴方識(shí)別到。
關(guān)于這點(diǎn)請(qǐng)自行百度查閱前置知識(shí),只要理解它的作用,代碼其實(shí)很簡(jiǎn)單。關(guān)于這點(diǎn)多說(shuō)一下,許久之前我曾經(jīng)有過(guò)疑惑,就是我編寫的Common包其中包含了使用spring注解@Component、@Service、@Controller等修飾的Bean,那么引入這個(gè)jar包的spring工程,如何能夠?qū)?/p>
這個(gè)Bean注入到spring上下文中呢,使用@ComponentScan掃描,顯然勉強(qiáng)能夠?qū)崿F(xiàn),但是如果所有引入的工程都去改寫@ComponentScan 顯然不現(xiàn)實(shí),spring.factories就可以靈活的實(shí)現(xiàn)該需求,自動(dòng)的將配置進(jìn)行導(dǎo)入
@EnableWebConfigure
@EnableWebConfigure 是我自定義的注解,期望用它來(lái)自動(dòng)開啟Web相關(guān)的公共能力,實(shí)現(xiàn)如下:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(WebMarkerConfiguration.class) public @interface EnableWebConfigure { }
注解標(biāo)識(shí)在啟動(dòng)類上即可,它并沒(méi)有屬性和方法,僅導(dǎo)入了另一個(gè)配置類 WebMarkerConfiguration.class
@Configuration public class WebMarkerConfiguration { @Bean public Marked createMarkedInstance(){ return new Marked(); } class Marked{ } }
可以看到,我很懶,連名字都跟EurekaServer中的實(shí)現(xiàn)一樣…
而引用此Marked標(biāo)識(shí)的是配置類 InternalCommonBeanConfiguration
@Configuration @Import({WebConfig.class, WebMvcConfig.class}) @ConditionalOnBean(WebMarkerConfiguration.Marked.class) public class InternalCommonBeanConfiguration { @Bean public GlobalExceptionInterceptor createGlobalExceptionInterceptor(){ // 全局異常處理 return new GlobalExceptionInterceptor(); } @Bean public TransIdFilter createTransIdFilter(){ // TraceId 過(guò)濾器 return new TransIdFilter(); } }
類中除了聲明GlobalExceptionInterceptor以及TransIdFilter,還導(dǎo)入了@Import({WebConfig.class, WebMvcConfig.class})
這兩個(gè)類用來(lái)配合@ResponseBody或者@RestController實(shí)現(xiàn)JSON序列化
最后,通過(guò)在internal-common工程resource文件下,新建 META-INF/spring.factories 文件,來(lái)暴露InternalCommonBeanConfiguration,以方便其他項(xiàng)目能夠在依賴時(shí),自動(dòng)導(dǎo)入。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.sun.online.internalcommon.configure.InternalCommonBeanConfiguration
具體工程中的應(yīng)用請(qǐng)見 org.sun.online.serviceverificationcode.ServiceVerificationCodeApplication
設(shè)計(jì)價(jià)值
依賴方:后續(xù)的Web服務(wù)工程中,只需要@EnableWebConfigure
即可獲得相應(yīng)的通用能力
被依賴方:通過(guò)拓展 InternalCommonBeanConfiguration
即可令所有依賴方無(wú)需代碼改動(dòng)直接獲得支持,方便升級(jí)維護(hù)
到此這篇關(guān)于Java使用@EnableEurekaServer實(shí)現(xiàn)自動(dòng)裝配詳解的文章就介紹到這了,更多相關(guān)Java @EnableEurekaServer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring security在分布式項(xiàng)目下的配置方法(案例詳解)
這篇文章主要介紹了spring security在分布式項(xiàng)目下的配置方法,本文通過(guò)一個(gè)項(xiàng)目案例給大家詳細(xì)介紹,通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10Spring案例打印機(jī)的實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了Spring案例打印機(jī)的實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10springboot+WebMagic+MyBatis爬蟲框架的使用
本文是對(duì)spring boot+WebMagic+MyBatis做了整合,使用WebMagic爬取數(shù)據(jù),然后通過(guò)MyBatis持久化爬取的數(shù)據(jù)到mysql數(shù)據(jù)庫(kù)。具有一定的參考價(jià)值,感興趣的可以了解一下2021-08-08Java的springcloud Sentinel是什么你知道嗎
這篇文章主要介紹了Java之springcloud Sentinel案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08SpringBoot實(shí)現(xiàn)簡(jiǎn)易支付寶網(wǎng)頁(yè)支付功能
小編最近實(shí)現(xiàn)一個(gè)功能基于springboot程序的支付寶支付demo,非常不錯(cuò)適合初學(xué)者入門學(xué)習(xí)使用,今天把SpringBoot實(shí)現(xiàn)簡(jiǎn)易支付寶網(wǎng)頁(yè)支付功能的示例代碼分享給大家,感興趣的朋友參考下吧2021-10-10詳解idea中web.xml默認(rèn)版本問(wèn)題解決
這篇文章主要介紹了詳解idea中web.xml默認(rèn)版本問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12SpringBoot登錄、退出、獲取用戶信息的session處理方案
這篇文章主要介紹了SpringBoot登錄、退出、獲取用戶信息的session處理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08