新聞中心
一、介紹
在實(shí)際的項(xiàng)目開發(fā)中,我們往往需要根據(jù)不同的環(huán)境做出不同的配置,例如:在開發(fā)環(huán)境下,我們會使用內(nèi)存數(shù)據(jù)庫以便快速啟動服務(wù)并進(jìn)行開發(fā)調(diào)試,在test環(huán)境、生產(chǎn)環(huán)境,會使用對應(yīng)環(huán)境的數(shù)據(jù)庫。

十多年的加查網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整加查建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“加查網(wǎng)站設(shè)計(jì)”,“加查網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
如果我們的應(yīng)用程序可以根據(jù)自身的環(huán)境做一些這樣的適配,那么我們的程序開發(fā)無疑將更加靈活、高效。
在過去的應(yīng)用程序開發(fā)中,我們常常會將這些環(huán)境變量寫在某個(gè)指定的配置文件中,每次服務(wù)器啟動的時(shí)候,會讀取服務(wù)器中指定的配置文件,從而實(shí)現(xiàn)根據(jù)不同的環(huán)境,應(yīng)用程序能做出對應(yīng)的適配。
但是這樣的工作,對于運(yùn)維來說,非常苦逼,尤其是應(yīng)用程序到達(dá)50個(gè)以上的時(shí)候,會非常不好維護(hù),每次上線改配置,全靠人肉,想想都覺得反人類~
當(dāng)我們在使用SpringBoot來開發(fā)應(yīng)用程序的時(shí)候,這些工作量將大大簡化。
SpringBoot為開發(fā)者提供了三種可選的條件裝配方式。
- Profile
- Conditional
- ConditionalOnProperty
下面,我們一起來了解一下具體的應(yīng)用實(shí)踐。
二、程序?qū)嵺`
2.1、Profile
SpringBoot 為應(yīng)用程序提供了Profile這一概念,用來表示不同的環(huán)境。例如,我們分別定義開發(fā)、測試和生產(chǎn)這3個(gè)環(huán)境
- dev:開發(fā)環(huán)境
- test:測試環(huán)境
- production:生產(chǎn)環(huán)境
以上傳文件為例,在開發(fā)環(huán)境下,我們將文件上傳到本地,而在測試環(huán)境、生產(chǎn)環(huán)境,我們將文件上傳到云端服務(wù)商。
1、首先編寫兩套上傳服務(wù)
- /**
- * 上傳文件到本地
- * @since 2021-06-13
- */
- public class FileUploader implements Uploader {
- @Override
- public String upload(File file) {
- //上傳文件到本地,并返回絕對路徑
- return null;
- }
- }
- /**
- * 上傳文件到OSS
- * @since 2021-06-13
- */
- public class OSSUploader implements Uploader {
- @Override
- public String upload(File file) {
- //上傳文件到云端,并返回絕對路徑
- return null;
- }
- }
2、然后編寫一個(gè)服務(wù)配置類,根據(jù)不同的環(huán)境,創(chuàng)建不同的實(shí)現(xiàn)類
- @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)前的Profile設(shè)置為dev,則Spring容器會調(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
2.2、Conditional
除了可以根據(jù)@Profile條件來決定是否創(chuàng)建某個(gè)Bean外,Spring還可以根據(jù)@Conditional決定是否創(chuàng)建某個(gè)Bean。
以發(fā)短信為例,在生產(chǎn)環(huán)境,我們會提供發(fā)短信服務(wù),而在其他環(huán)境,我們不會向運(yùn)營商發(fā)短信。
1、創(chuàng)建一個(gè)條件配置類SMSEnvCondition
- public class SMSEnvCondition implements Condition {
- @Override
- public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
- return "true".equalsIgnoreCase(context.getEnvironment().getProperty("enable.sms"));
- }
- }
2、創(chuàng)建一個(gè)發(fā)短信的服務(wù)
- @Component
- @Conditional(SMSEnvCondition.class)
- public class SendMessageService {
- //...
- }
3、在application.properties文件中,添加配置變量enable.sms
- enable.sms=true
當(dāng)enable.sms為true的時(shí)候,會創(chuàng)建SendMessageService對象,否則不創(chuàng)建。
2.3、ConditionalOnProperty
Spring提供的條件裝配@Conditional,靈活性非常強(qiáng),但是具體判斷邏輯還需要我們自己實(shí)現(xiàn),比較麻煩。
實(shí)際上,Spring Boot為開發(fā)者提供了很多使用起來更簡單的條件注解,例如:
- ConditionalOnProperty:如果有指定的配置,條件生效
- ConditionalOnBean:如果有指定的Bean,條件生效
- ConditionalOnMissingBean:如果沒有指定的Bean,條件生效
- ConditionalOnMissingClass:如果沒有指定的Class,條件生效
- ConditionalOnWebApplication:在Web環(huán)境中條件生效
- ConditionalOnExpression:根據(jù)表達(dá)式判斷條件是否生效
我們以最常用的@ConditionalOnProperty注解為例,將上面的代碼改成如下方式即可實(shí)現(xiàn)按照條件進(jìn)行加載。
- @Component
- @ConditionalOnProperty(name="enable.sms", havingValue="true")
- public class SendMessageService {
- //...
- }
當(dāng)enable.sms的值等于true時(shí),會實(shí)例化SendMessageService對象;反之,不會創(chuàng)建對象。
是不是超級簡單~~~
當(dāng)然@ConditionalOnProperty的參數(shù)還不僅僅限于此,以上面上傳文件為例,在開發(fā)環(huán)境,我們總是上傳到本地;在測試環(huán)境、生產(chǎn)環(huán)境,我們將文件上傳到云端,改造過程如下:
- @Component
- @ConditionalOnProperty(name = "file.storage", havingValue = "file", matchIfMissing = true)
- public class FileUploader implements Uploader {
- @Override
- public String upload(File file) {
- //上傳文件到本地,并返回絕對路徑
- return null;
- }
- }
- @Component
- @ConditionalOnProperty(name = "file.storage", havingValue = "oss")
- public class OSSUploader implements Uploader {
- @Override
- public String upload(File file) {
- //上傳文件到云端,并返回絕對路徑
- return null;
- }
- }
當(dāng)file.storage配置值為file,會加載FileUploader類;當(dāng)file.storage配置值為oss,會加載OSSUploader類。
其中@ConditionalOnProperty中的matchIfMissing參數(shù)表示,當(dāng)沒有找到對應(yīng)配置參數(shù)時(shí),會默認(rèn)加載當(dāng)前類,也就是FileUploader類。
三、小結(jié)
雖然,@Profile、@Conditional、@ConditionalOnProperty三個(gè)注解都能實(shí)現(xiàn)按照條件進(jìn)行適配,但是@Profile注解控制比較粗糙,很難實(shí)現(xiàn)精細(xì)化控制。
在實(shí)際的使用過程中,使用最多的是@Conditional、@ConditionalOnProperty,可以很靈活的實(shí)現(xiàn)條件裝配。
其中,@ConditionalOnProperty是@Conditional的一種具體擴(kuò)展實(shí)現(xiàn),提供了很多非常實(shí)用的操作,在使用中,推薦大家使用@ConditionalOnProperty。
如果不夠,可以根據(jù)@Conditional條件裝配,編寫一套控制開關(guān)實(shí)現(xiàn)類。
網(wǎng)頁題目:SpringBoot的條件裝配,徹底愛了!
文章分享:http://m.fisionsoft.com.cn/article/dpidehc.html


咨詢
建站咨詢
