SpringBoot@Profile注解和Spring?EL(多環(huán)境注入)
前言
本篇文章主要講訴多環(huán)境注入適應(yīng)不同場景問題和Spring EL。
一、@Profile
- 在企業(yè)開發(fā)的過程中,項目往往要面臨開發(fā)環(huán)境、測試環(huán)境、準(zhǔn)生產(chǎn)環(huán)境(用于模擬真實生產(chǎn)環(huán)境部署所用〉和生產(chǎn)環(huán)境等的切換,所以在企業(yè)開發(fā)中往往需要有多套環(huán)境,而每一套環(huán)境的上下文是不一樣的。例如,它們會有各自的數(shù)據(jù)庫資源,這樣就要求我們在不同的數(shù)據(jù)庫之間進(jìn)行切換。為了方便, Spring還提供了 Profile機(jī)制, 使我們可以很方便地實現(xiàn)各個環(huán)境之間的切換。在使用DI來依賴注入的時候,能夠根據(jù)@profile標(biāo)明的環(huán)境,將注入符合當(dāng)前運行環(huán)境的相應(yīng)的bean。
- 使用要求:
- @Component或@Configuration注解的類可以使用@profile
- @Profile中需要指定一個字符串,約定生效的環(huán)境
注解使用
(1) @Prifile修飾類
@Configuration @Profile("dev") public class MyConfig{ @Bean(destroyMethod="destory") public DataSource getDevDataSource () { Properties props = new Properties(); props.setProperty("driver","com.mysql.jdbc.Driver"); props.setProperty("url","jdbc:mysql://localhost:3306/dev_spring_boot") ; props.setProperty("sername","root"); props.setProperty ("password","root") ; DataSource dataSource = null; try { dataSource = BasicDataSourceFactory.createDataSource(props) ; } catch (Exception e) { e.printStackTrace() ; } return dataSource; } }
(2)@Profile修飾方法
現(xiàn)在有兩個數(shù)據(jù)庫,使用注解@Profile 定義兩個Bean
@Bean(name = "dataSource", destroyMethod = "close" ) @Profile("dev") public DataSource getDevDataSource () { Properties props = new Properties(); props.setProperty("driver","com.mysql.jdbc.Driver"); props.setProperty("url","jdbc:mysql://localhost:3306/dev_spring_boot") ; props.setProperty("sername","root"); props.setProperty ("password","root") ; DataSource dataSource = null; try { dataSource = BasicDataSourceFactory.createDataSource(props) ; } catch (Exception e) { e.printStackTrace() ; } return dataSource; } @Bean(name = "dataSource",destroyMethod = "close") @Profile("test") public DataSource getTestDataSource () { Properties props= new Properties() ; props.setProperty("driver", "com.mysql.jdbc.Driver"); props.setProperty("url","jdbc:mysql://localhost:3306/test_spring_boot"); props.setProperty("username","root") ; props.setProperty("password", "root") ; DataSource dataSource = null; try { dataSource = BasicDataSourceFactory.createDataSource(props); }catch (Exception e) { e.printStackTrace(); } return dataSource; }
(3)@Profile修飾注解
了一個注解實現(xiàn)自定義場景,該注解可以使注入的bean使用dev的這個場景,后續(xù)就不再需要使用@Profile(“dev”)的方式,只需要在使用@Dev。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Profile("dev") public @interface Dev { }
(4)啟動激活
在 Spring 中存在兩個參數(shù)可以提供給我們配置,以修改啟動 Profile 機(jī)制, 一個是spring.profiles.active, 另一個是 spring.profiles.default。在這兩個屬性都沒有配置的情況下, Spring 將不會啟動Profile 機(jī)制,這就意味著被@Profile 標(biāo)注的 Bean 將不會被 Spring裝配到 roe 容器中。Spring是先判定是否存在spring.profiles.active 配置后 , 再去查找 spring.profiles.default 配置的,所以spring.profiles.active 的優(yōu)先級要大于 spring.profiles.default。
在Java 啟動項目中,使用dev環(huán)境,我們只需要如下配置就能夠啟動Profile機(jī)制(idea和eclipse的配置):
也可以打包后運行:
java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;
資源配置文件
- springboot的環(huán)境隔離還可以使用多資源文件的方式,進(jìn)行一些參數(shù)的配置。
- Springboot的資源配置文件除了application.properties之外,還可以有對應(yīng)的資源文件application-{profile}.properties。
假設(shè),一個應(yīng)用的工作環(huán)境有:dev、test、prod
那么,我們可以添加 4 個配置文件:
- applcation.properties : 公共配置
- application-dev.properties : 開發(fā)環(huán)境配置
- application-test.properties : 測試環(huán)境配置
- application-prod.properties : 生產(chǎn)環(huán)境配置
- 不同的properties配置文件也可以是在 applcation.properties 文件中來激活 profile:spring.profiles.active = dev
- 這個時候請注意,按照 Spring Boot 的規(guī)則,假設(shè)把選項-Dspring.profiles.active 配置的值記為{profile},則它會用 application-{profile}.properties 文件去代替原來默認(rèn)的 application.properties 文件,然后啟動Spring Boot 的程序。
例如:
application.properties:
spring.profiles.active=prod
application-prod.properties:
server.port=2222 #定義一些自己使用的屬性,然后通過@Value("${屬性名}}")注解來加載對應(yīng)的配置屬性 com.name=Prod com.location=Hubei
application-dev.properties:
# 服務(wù)端口 server.port=1111 #定義一些自己使用的屬性,然后通過@Value("${屬性名}}")注解來加載對應(yīng)的配置屬性 com.name=DEV com.location=HeNan
控制層:
@Controller @RequestMapping("/test") public class test { @Value("${com.name}") private String name; @Value("${com.location}") private String location; @RequestMapping("hello") @ResponseBody public String test1(){ System.out.println(name + "hello Spring Boot, " +location); return name + ",hello Spring Boot! " +location; } }
啟動Springboot后,訪問http://localhost:2222/test/hello如下:
訪問http://localhost:1111/test/hello是報錯的,因為此時激活的是prod環(huán)境,使用的是application-dev.properties配置文件。
二、Spring EL
為了更加靈活, Spring還提供了表達(dá)式語言Spring EL。通過 Spring EL 可以擁有更為強(qiáng)大的運算規(guī)則來更好地裝配Bean。
最常用的當(dāng)然是讀取屬性文件的值, 例如
@Value("${database.driverName}") String driver
這里的@Value 中的${......}代表占位符,它會讀取上下文的屬性值裝配到屬性中,這便是一個最簡單的Spring 表達(dá)式。 除此之外,它還能夠調(diào)用方法,例如,我們記錄一個Bean 的初始化時間:
@Value ("#{T(System).currentTimeMillis()}") private Long initTime = null;
- 這里采用 #{.....}代表啟用 Spring 表達(dá)式,它將具有運算的功能;
- T(…)代表的是引入類:System 是java.lang.*包的類, 這是 Java 默認(rèn)加載的包,因此可以不必寫全限定名,如果是其他的包,則需要寫出全限定名才能引用類: currentTimeMillis 是它的靜態(tài)(static)方法,也就是我們調(diào)用一次System.currentTimeMillis()方法來為這個屬性賦值。
此外還可以給屬性直接進(jìn)行賦值:
//賦值字符串 @Value( "#{'使用 Spring EL 賦值字符串'}") private String str = null; //科學(xué)計數(shù)法賦值 @Value("#(9.3E3}") private double d; //賦值浮點數(shù) @Value ("#(3.14 }") private float pi;
還可以獲取其他Spring Bean 的屬性來給當(dāng)前的Bean屬性賦值:
@Value ("#{beanName.str}") private String otherBeanProp = null;
- beanName 是 Spring IoC 容器 Bean 的名稱。
- str 是其屬性,代表引用對應(yīng)的 Bean的屬性給當(dāng)前屬性賦值。
有時候, 我們還希望這個屬性的宇母全部變?yōu)榇髮懀@個時候就可以寫成:
@Value("#{beanName.str?.toUpperCase()}") private String otherBeanProp = null;
再次注意這里的Spring EL。這里引用由屬性后跟著是一個?,這個符號的含義是判斷這個屬性是否為空。如果不為空才會去執(zhí)行toUppercase 方法,進(jìn)而把引用到的屬性轉(zhuǎn)換為大寫,賦予當(dāng)前屬性。
還可以使用 Spring EL進(jìn)行一定的運算:
# 數(shù)學(xué)運算 @Value ("#{1+2}") private int run; # 浮點數(shù)比較運算 @Value ("#{beanName.pi == 3.14f}") private boolean piFlag; # 字符串比較運算 @Value ("#{beanName.str eq 'Spring Boot'}") pri. vate boolean strFlag; # 字符串連接 @Value ("#{beanName.str + ' 連接字符串 '}") private String strApp = null; # 三元運算 @Value ("#{beanName.d > 1000 ? '大子' : '小子'}") private String resultDesc = null;
從上面的代碼可以看出, SpringEL 能夠支持的運算還有很多,其中等值比較如果是數(shù)字型的可以使用=比較符,如果是字符串型的可以使用 eq 比較符。
總結(jié)
以上就是多環(huán)境注入和Spring EL的全部講解。
到此這篇關(guān)于SpringBoot@Profile注解和Spring EL的文章就介紹到這了,更多相關(guān)SpringBoot@Profile注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實現(xiàn)解析二進(jìn)制文件的方法(字符串、圖片)
本篇文章主要介紹了java實現(xiàn)解析二進(jìn)制文件的方法(字符串、圖片),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02springboot cloud使用eureka整合分布式事務(wù)組件Seata 的方法
這篇文章主要介紹了springboot cloud使用eureka整合分布式事務(wù)組件Seata 的方法 ,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-05-05SpringBoot如何通過Feign調(diào)用傳遞Header中參數(shù)
這篇文章主要介紹了SpringBoot通過Feign調(diào)用傳遞Header中參數(shù),本文給大家分享兩種解決方案給大家詳細(xì)講解,需要的朋友可以參考下2023-04-04SpringBoot與單元測試JUnit的結(jié)合操作
這篇文章主要介紹了SpringBoot與單元測試JUnit的結(jié)合操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10