Spring 中如何根據(jù)環(huán)境切換配置 @Profile
Spring 根據(jù)環(huán)境切換配置 @Profile
我們實際開發(fā)中往往有多個環(huán)境,比如測試環(huán)境、開發(fā)環(huán)境、生產環(huán)境等;不同的環(huán)境往往配置也有區(qū)別,一直切換環(huán)境的配置很麻煩,Spring 為我們提供了一個注解,可以快速切換環(huán)境配置。
@Profile
我們新建一個配置,作用是注冊三個數(shù)據(jù)源,因為不同的環(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;
// 指定組件在那個環(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 注解來表示對應的環(huán)境,也就是說當指定環(huán)境之后,只有標注對應環(huán)境名的 Bean 才能被注冊到容器中去,沒有標注任何 @Profile 的方法默認直接注冊進去。
環(huán)境區(qū)分好了如何啟動對應的環(huán)境?
有兩種方式:
- 使用命令行參數(shù);
- 使用無參構造創(chuàng)建容器;
在 IDEA 中可以設置啟動參數(shù),加上如下參數(shù):
-Dspring.profiles.active=test
其中 test 可以換成在 @Profile 中配置的名稱。

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

Spring配置profile,切換開發(fā)環(huán)境和測試生產環(huán)境
項目的開發(fā)環(huán)境和測試生產環(huán)境要配置的數(shù)據(jù)庫,redis等等,連接地址都不一樣。這樣在項目部署到測試,生產時總要挨個修改這些配置。通過Spring的profile可以控制在不同的環(huán)境在Spring容器中注冊不同的配置Bean,然后用一個總開關控制在什么環(huán)境用什么配置。
public interface CompactDisc {
void play();
}
有兩個類實現(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("------進入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類里有一個CompactDisc 的注入,由于上面MovieDisc 和MusicDisc 都實現(xiàn)了CompactDisc ,那么在Spring容器啟動是就要選擇一個注冊,這個選擇是通過@Profile(“pro”)注解標識的。然后通過在webxml里面添加spring.profiles.default控制
具體的控制規(guī)則如下:
xml里面配置了spring.profiles.default和spring.profiles.active,當沒有active時默認defalult中配置的dev,對應配置類中@Profile(“dev”)標識的MusicDisc會被創(chuàng)建;當配置了active時,@Profile(“dev”)會被創(chuàng)建。未被@Profile標識的bean始終會被創(chuàng)建。所以根據(jù)上面的配置,當訪問http://localhost:8080/Spring/disc 時輸出是
------進入controller--------
泰坦尼克號
這樣在部署不同的環(huán)境時通過控制spring.profiles.active和就ok了,而不必去一個一個的修改那些配置了。
xml配置方式
<beans profile="pro">
<bean id="compactDisc" class="com.xu.MusicDisc"></bean>
</beans>
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
springboot jpa實現(xiàn)優(yōu)雅處理isDelete的默認值
如果多個實體類都有 isDelete 字段,并且你希望在插入時為它們統(tǒng)一設置默認值時改怎么做呢,本文為大家整理了一些方法,希望對大家有所幫助2024-11-11
Spring中的@ConfigurationProperties在方法上的使用詳解
這篇文章主要介紹了Spring中的@ConfigurationProperties在方法上的使用詳解,@ConfigurationProperties應該經常被使用到,作用在類上的時候,將該類的屬性取值?與配置文件綁定,并生成配置bean對象,放入spring容器中,提供給其他地方使用,需要的朋友可以參考下2024-01-01
Spring Security和自定義filter的沖突導致多執(zhí)行的解決方案
這篇文章主要介紹了Spring Security和自定義filter的沖突導致多執(zhí)行的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
SpringBoot配置數(shù)據(jù)庫密碼加密的方法
由于系統(tǒng)安全的考慮,配置文件中不能出現(xiàn)明文密碼的問題,本文就給大家詳細介紹下springboot配置數(shù)據(jù)庫密碼加密的方法,下面話不多說了,來一起看看詳細的介紹吧,需要的朋友可以參考下2023-08-08
java對象list使用stream根據(jù)某一個屬性轉換成map的3種方式舉例
開發(fā)小伙伴們通常會需要使用到對象和Map互相轉換的開發(fā)場景,下面這篇文章主要給大家介紹了關于java對象list使用stream根據(jù)某一個屬性轉換成map的3種方式,需要的朋友可以參考下2024-01-01

