SpringBoot中的條件裝配方法
在實(shí)際的項(xiàng)目開(kāi)發(fā)中,我們往往需要根據(jù)不同的環(huán)境做出不同的配置,例如:在開(kāi)發(fā)環(huán)境下,我們會(huì)使用內(nèi)存數(shù)據(jù)庫(kù)以便快速啟動(dòng)服務(wù)并進(jìn)行開(kāi)發(fā)調(diào)試,在test環(huán)境、生產(chǎn)環(huán)境,會(huì)使用對(duì)應(yīng)環(huán)境的數(shù)據(jù)庫(kù)。
如果我們的應(yīng)用程序可以根據(jù)自身的環(huán)境做一些這樣的適配,那么我們的程序開(kāi)發(fā)無(wú)疑將更加靈活、高效。
在過(guò)去的應(yīng)用程序開(kāi)發(fā)中,我們常常會(huì)將這些環(huán)境變量寫(xiě)在某個(gè)指定的配置文件中,每次服務(wù)器啟動(dòng)的時(shí)候,會(huì)讀取服務(wù)器中指定的配置文件,從而實(shí)現(xiàn)根據(jù)不同的環(huán)境,應(yīng)用程序能做出對(duì)應(yīng)的適配。
但是這樣的工作,對(duì)于運(yùn)維來(lái)說(shuō),非常苦逼,尤其是應(yīng)用程序到達(dá)50個(gè)以上的時(shí)候,會(huì)非常不好維護(hù),每次上線(xiàn)改配置~
當(dāng)我們?cè)谑褂肧pringBoot來(lái)開(kāi)發(fā)應(yīng)用程序的時(shí)候,這些工作量將大大簡(jiǎn)化。
SpringBoot為開(kāi)發(fā)者提供了三種可選的條件裝配方式。
● Profile
● Conditional
● ConditionalOnProperty
在Spring Boot中,條件裝配(Conditional Bean Configuration)是指根據(jù)特定的條件來(lái)決定是否創(chuàng)建或裝配某個(gè)Bean。以下是幾種常用的條件裝配方式及其代碼示例:
Spring提供的條件裝配@Conditional,靈活性非常強(qiáng),但是具體判斷邏輯還需要我們自己實(shí)現(xiàn),比較麻煩。
實(shí)際上,Spring Boot為開(kāi)發(fā)者提供了很多使用起來(lái)更簡(jiǎn)單的條件注解,例如:
● ConditionalOnProperty:如果有指定的配置,條件生效
● ConditionalOnBean:如果有指定的Bean,條件生效
● ConditionalOnMissingBean:如果沒(méi)有指定的Bean,條件生效
● ConditionalOnMissingClass:如果沒(méi)有指定的Class,條件生效
● ConditionalOnWebApplication:在Web環(huán)境中條件生效
● ConditionalOnExpression:根據(jù)表達(dá)式判斷條件是否生效
Profile
SpringBoot 為應(yīng)用程序提供了Profile這一概念,用來(lái)表示不同的環(huán)境。例如,我們分別定義開(kāi)發(fā)、測(cè)試和生產(chǎn)這3個(gè)環(huán)境
dev:開(kāi)發(fā)環(huán)境
test:測(cè)試環(huán)境
production:生產(chǎn)環(huán)境
以上傳文件為例,在開(kāi)發(fā)環(huán)境下,我們將文件上傳到本地,而在測(cè)試環(huán)境、生產(chǎn)環(huán)境,我們將文件上傳到云端服務(wù)商。
1、首先編寫(xiě)兩套上傳服務(wù) /** ● 上傳文件到本地 ● @since 2021-06-13 */ public class FileUploader implements Uploader { @Override public String upload(File file) { //上傳文件到本地,并返回絕對(duì)路徑 return null; } } /** ● 上傳文件到OSS ● @since 2021-06-13 */ public class OSSUploader implements Uploader { @Override public String upload(File file) { //上傳文件到云端,并返回絕對(duì)路徑 return null; } }
2、然后編寫(xiě)一個(gè)服務(wù)配置類(lèi),根據(jù)不同的環(huán)境,創(chuàng)建不同的實(shí)現(xiàn)類(lèi)
@Configuration public class AppConfig { @Bean @Profile("dev") public Uploader initFileUploader() { System.out.println("初始化一個(gè)上傳到本地的bean"); return new FileUploader(); } @Bean @Profile("!dev") public Uploader initOSSUploader() { System.out.println("初始化一個(gè)上傳到云端的bean"); return new OSSUploader(); } }
3、最后,運(yùn)行程序
在運(yùn)行程序時(shí),加上JVM參數(shù)-Dspring.profiles.active=dev就可以指定以dev環(huán)境啟動(dòng)。
如果當(dāng)前的Profile設(shè)置為dev,則Spring容器會(huì)調(diào)用initFileUploader()創(chuàng)建FileUploader,否則,調(diào)用initOSSUploader()創(chuàng)建OSSUploader。
注意:@Profile(“!dev”)表示非dev環(huán)境。
當(dāng)然,你還可以在application.properties文件中加上如下配置,一樣可以指定環(huán)境進(jìn)行運(yùn)行。
spring.profiles.active=dev
1. @Conditional 注解
@Conditional允許基于自定義條件進(jìn)行裝配。
代碼示例:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean @Conditional(MyCondition.class) public MyService myService() { return new MyService(); } }
自定義條件:
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class MyCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 判斷條件,返回true表示創(chuàng)建該bean return true; // 可以根據(jù)環(huán)境變量、系統(tǒng)屬性等來(lái)判斷 // return "true".equalsIgnoreCase(context.getEnvironment().getProperty("enable.sms")); } }
2. @ConditionalOnProperty 注解
根據(jù)配置文件中的屬性值決定是否裝配某個(gè)Bean。
代碼示例:
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean @ConditionalOnProperty(name = "feature.enabled", havingValue = "true") public MyService myService() { return new MyService(); } }
配置文件:
eature: enabled: true
@ConditionalOnClass 注解
如果某個(gè)類(lèi)在類(lèi)路徑上存在,則裝配相應(yīng)的Bean。
代碼示例:
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean @ConditionalOnClass(name = "com.example.SomeClass") public MyService myService() { return new MyService(); } }
4. @ConditionalOnMissingBean 注解
如果容器中不存在某個(gè)Bean,則裝配當(dāng)前的Bean。
代碼示例:
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean @ConditionalOnMissingBean public MyService myService() { return new MyService(); } }
5. @ConditionalOnBean 注解
如果容器中存在某個(gè)特定的Bean,則裝配當(dāng)前的Bean。
代碼示例:
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean @ConditionalOnBean(name = "someOtherBean") public MyService myService() { return new MyService(); } }
6. @ConditionalOnExpression 注解
根據(jù)SpEL表達(dá)式的結(jié)果來(lái)決定是否裝配Bean。
代碼示例:
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean @ConditionalOnExpression("${feature.enabled:true} == true") public MyService myService() { return new MyService(); } }
這些注解幫助你根據(jù)不同的條件動(dòng)態(tài)地裝配Bean,使得Spring Boot應(yīng)用更加靈活和可配置。
到此這篇關(guān)于SpringBoot中的條件裝配方法的文章就介紹到這了,更多相關(guān)SpringBoot條件裝配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中的AOP動(dòng)態(tài)代理源碼詳解
這篇文章主要介紹了Spring中的AOP動(dòng)態(tài)代理源碼詳解,AOP即面向切面編程也稱(chēng)面向方面編程,它是面向?qū)ο缶幊蘋(píng)OP的一種補(bǔ)充,目前已成為一種比較成熟的編程方式,本文就其源碼進(jìn)行解析,需要的朋友可以參考下2023-09-09JAVA中使用JSON進(jìn)行數(shù)據(jù)傳遞示例
本篇文章主要介紹了JAVA中使用JSON進(jìn)行數(shù)據(jù)傳遞示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01Spring Boot應(yīng)用發(fā)布到Docker的實(shí)現(xiàn)
這篇文章主要介紹了Spring Boot應(yīng)用發(fā)布到Docker的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06解決BufferedReader.readLine()遇見(jiàn)的坑
這篇文章主要介紹了解決BufferedReader.readLine()遇見(jiàn)的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12Spring+SpringMVC+Hibernate整合實(shí)例講解
在本篇文章里小編給大家整理的是關(guān)于Spring+SpringMVC+Hibernate整合實(shí)例講解,需要的朋友們可以學(xué)習(xí)下。2020-03-03Java外觀(guān)模式解讀,讓你的代碼優(yōu)雅又高效
外觀(guān)模式(Facade?Pattern)是一種常用的結(jié)構(gòu)型設(shè)計(jì)模式,它為復(fù)雜的子系統(tǒng)提供一個(gè)簡(jiǎn)單的接口,隱藏復(fù)雜的實(shí)現(xiàn)細(xì)節(jié),本文就來(lái)講講它是如何簡(jiǎn)化代碼,提高可維護(hù)性的2023-05-05JAVA代碼設(shè)置selector不同狀態(tài)下的背景顏色
這篇文章主要介紹了JAVA代碼設(shè)置selector不同狀態(tài)下的背景顏色,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-05-05