Spring 中如何根據(jù)環(huán)境切換配置 @Profile
Spring 根據(jù)環(huán)境切換配置 @Profile
我們實(shí)際開發(fā)中往往有多個(gè)環(huán)境,比如測試環(huán)境、開發(fā)環(huán)境、生產(chǎn)環(huán)境等;不同的環(huán)境往往配置也有區(qū)別,一直切換環(huán)境的配置很麻煩,Spring 為我們提供了一個(gè)注解,可以快速切換環(huán)境配置。
@Profile
我們新建一個(gè)配置,作用是注冊三個(gè)數(shù)據(jù)源,因?yàn)椴煌沫h(huán)境使用的數(shù)據(jù)庫一般不一樣:
@Configuration
@PropertySource("classpath:/person.properties")
public class MainConfigOfProfile implements EmbeddedValueResolverAware {
@Value("${db.user}")
private String user;
@Value("${db.url}")
private String url;
private String driver;
// 指定組件在那個(gè)環(huán)境下才能注冊到組件中: 不指定則都能注冊
@Profile("test")
@Bean("testDataSource")
public DataSource dataSourceTest(@Value("${db.password}") String pwd) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl(url);
dataSource.setDriverClass(driver);
return dataSource;
}
@Profile("dev")
@Bean("devDataSource")
public DataSource dataSourceDev(@Value("${db.password}") String pwd) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl(url);
dataSource.setDriverClass(driver);
return dataSource;
}
@Profile("prod")
@Bean("prodDataSource")
public DataSource dataSourceProd(@Value("${db.password}") String pwd) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl(url);
dataSource.setDriverClass(driver);
return dataSource;
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.driver = resolver.resolveStringValue("${db.driver}");
}
}
這里在方法上使用了 @Profile 注解來表示對應(yīng)的環(huán)境,也就是說當(dāng)指定環(huán)境之后,只有標(biāo)注對應(yīng)環(huán)境名的 Bean 才能被注冊到容器中去,沒有標(biāo)注任何 @Profile 的方法默認(rèn)直接注冊進(jìn)去。
環(huán)境區(qū)分好了如何啟動對應(yīng)的環(huán)境?
有兩種方式:
- 使用命令行參數(shù);
- 使用無參構(gòu)造創(chuàng)建容器;
在 IDEA 中可以設(shè)置啟動參數(shù),加上如下參數(shù):
-Dspring.profiles.active=test
其中 test 可以換成在 @Profile 中配置的名稱。

這樣就能指定環(huán)境啟動了,還可以使用無參構(gòu)造創(chuàng)建容器。
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("prod", "dev");
context.register(MainConfigOfProfile.class);
context.refresh();
都是可以的,這里同時(shí)指定了兩個(gè)環(huán)境:prod 和 dev。
@Profile 也可以放在類上,這樣整個(gè)類就對應(yīng)指定的環(huán)境名。
在 IDEA 中,還可以使用圖形化界面快速切換所在的環(huán)境。

Spring配置profile,切換開發(fā)環(huán)境和測試生產(chǎn)環(huán)境
項(xiàng)目的開發(fā)環(huán)境和測試生產(chǎn)環(huán)境要配置的數(shù)據(jù)庫,redis等等,連接地址都不一樣。這樣在項(xiàng)目部署到測試,生產(chǎn)時(shí)總要挨個(gè)修改這些配置。通過Spring的profile可以控制在不同的環(huán)境在Spring容器中注冊不同的配置Bean,然后用一個(gè)總開關(guān)控制在什么環(huán)境用什么配置。
public interface CompactDisc {
void play();
}
有兩個(gè)類實(shí)現(xiàn)了它
public class MusicDisc implements CompactDisc {
private String music = "菊花臺";
/**
* @see com.xu.CompactDisc#play()
*/
@Override
public void play() {
System.out.println(music);
}
}
public class MovieDisc implements CompactDisc {
private String MovieConfig = "泰坦尼克號";
/**
* @see com.xu.CompactDisc#play()
*/
@Override
public void play() {
musicDisc.play();
}
}
基于java配置
@Configuration
public class MusicConfig {
@Bean
@Profile("dev")
public CompactDisc musicDisc(){
return new MusicDisc();
}
}
@Configuration
public class MovieConfig {
@Bean
@Profile("pro")
public CompactDisc movieDisc(){
return new MovieDisc();
}
}
@Controller
public class DiscController {
@Autowired(required=false)
private CompactDisc disc;
@RequestMapping("/disc")
public String disc(){
System.out.println("------進(jìn)入controller--------");
musicDisc.play();
return "ewr";
}
}
web.xml配置
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>pro</param-value>
</context-param>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</init-param>
<init-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</init-param>
<load-on-startup> 1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Controller類里有一個(gè)CompactDisc 的注入,由于上面MovieDisc 和MusicDisc 都實(shí)現(xiàn)了CompactDisc ,那么在Spring容器啟動是就要選擇一個(gè)注冊,這個(gè)選擇是通過@Profile(“pro”)注解標(biāo)識的。然后通過在webxml里面添加spring.profiles.default控制
具體的控制規(guī)則如下:
xml里面配置了spring.profiles.default和spring.profiles.active,當(dāng)沒有active時(shí)默認(rèn)defalult中配置的dev,對應(yīng)配置類中@Profile(“dev”)標(biāo)識的MusicDisc會被創(chuàng)建;當(dāng)配置了active時(shí),@Profile(“dev”)會被創(chuàng)建。未被@Profile標(biāo)識的bean始終會被創(chuàng)建。所以根據(jù)上面的配置,當(dāng)訪問http://localhost:8080/Spring/disc 時(shí)輸出是
------進(jìn)入controller--------
泰坦尼克號
這樣在部署不同的環(huán)境時(shí)通過控制spring.profiles.active和就ok了,而不必去一個(gè)一個(gè)的修改那些配置了。
xml配置方式
<beans profile="pro">
<bean id="compactDisc" class="com.xu.MusicDisc"></bean>
</beans>
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot jpa實(shí)現(xiàn)優(yōu)雅處理isDelete的默認(rèn)值
如果多個(gè)實(shí)體類都有 isDelete 字段,并且你希望在插入時(shí)為它們統(tǒng)一設(shè)置默認(rèn)值時(shí)改怎么做呢,本文為大家整理了一些方法,希望對大家有所幫助2024-11-11
迪米特法則_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了迪米特法則,迪米特法則就是一個(gè)在類創(chuàng)建方法和屬性時(shí)需要遵守的法則,有興趣的可以了解一下2017-08-08
Spring中的@ConfigurationProperties在方法上的使用詳解
這篇文章主要介紹了Spring中的@ConfigurationProperties在方法上的使用詳解,@ConfigurationProperties應(yīng)該經(jīng)常被使用到,作用在類上的時(shí)候,將該類的屬性取值?與配置文件綁定,并生成配置bean對象,放入spring容器中,提供給其他地方使用,需要的朋友可以參考下2024-01-01
Spring Security和自定義filter的沖突導(dǎo)致多執(zhí)行的解決方案
這篇文章主要介紹了Spring Security和自定義filter的沖突導(dǎo)致多執(zhí)行的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
SpringBoot配置數(shù)據(jù)庫密碼加密的方法
由于系統(tǒng)安全的考慮,配置文件中不能出現(xiàn)明文密碼的問題,本文就給大家詳細(xì)介紹下springboot配置數(shù)據(jù)庫密碼加密的方法,下面話不多說了,來一起看看詳細(xì)的介紹吧,需要的朋友可以參考下2023-08-08
springmvc整合freemarker配置的詳細(xì)步驟
本篇文章主要介紹了springmvc整合freemarker的詳細(xì)步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05
java對象list使用stream根據(jù)某一個(gè)屬性轉(zhuǎn)換成map的3種方式舉例
開發(fā)小伙伴們通常會需要使用到對象和Map互相轉(zhuǎn)換的開發(fā)場景,下面這篇文章主要給大家介紹了關(guān)于java對象list使用stream根據(jù)某一個(gè)屬性轉(zhuǎn)換成map的3種方式,需要的朋友可以參考下2024-01-01
springboot使用注解實(shí)現(xiàn)鑒權(quán)功能
這篇文章主要介紹了springboot使用注解實(shí)現(xiàn)鑒權(quán)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-12-12

