您好,登錄后才能下訂單哦!
Profile的意思是配置,對于應用程序來說,不同的環境需要不同的配置。
比如:
Spring框架提供了多profile的管理功能,我們可以使用profile功能來區分不同環境的配置。
首先,我們先看看如何基于Profile來定義一個Bean。
通過@Profile注解可以為一個Bean賦予對應的profile名稱,如下:
@Component
@Profile("dev")
public class DevDatasourceConfig
上面的DevDatasourceConfig被定義為 profile=dev,于是該Bean只會在dev(開發環境)模式下被啟用。
如果需要定義為非dev環境,可以使用這樣的形式:
@Component
@Profile("!dev")
public class DevDatasourceConfig
XML風格配置
上面的例子也可以使用XML配置文件達到同樣的目的,如下:
<beans profile="dev">
<bean id="devDatasourceConfig"
class="org.baeldung.profiles.DevDatasourceConfig" />
</beans>
讀取Profile
通過ConfigurableEnvironment這個Bean 可以獲得當前的Profile,如下:
public class ProfileManager {
@Autowired
Environment environment;
public void getActiveProfiles() {
for (final String profileName : environment.getActiveProfiles()) {
System.out.println("Currently active profile - " + profileName);
}
}
}
接下來,為了讓容器"僅僅注冊那些所需要的Bean",我們需要通過一些手段來設置當前的profile。
有很多方法可以達到這個目的,下面一一介紹。
在Web應用程序中,通過WebApplicationInitializer可以對當前的ServletContext進行配置。
如下,通過注入spring.profiles.active變量可以為Spring上下文指定當前的 profile:
@Configuration
public class MyWebApplicationInitializer
implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter(
"spring.profiles.active", "dev");
}
}
與上面的方法類似,在web.xml中通過context-param元素也可以設置profile。
但前提是當前應用程序使用了xml的配置文件風格,如下:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-config.xml</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
通過Java程序啟動參數同樣可以對profile進行設定,如下:
java -jar application.jar -Dspring.profiles.active=dev
spring-boot-maven-plugin插件也支持設定profile,其原理也是通過啟動參數實現,可以參考這里
https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/run-profiles.html
在Unix/Linux環境中,可以通過環境變量注入profile的值:
export spring_profiles_active=dev
java -jar application.jar
可以在application.properties配置文件中指定spring.profiles.active屬性:
spring.profiles.active=dev
SpringBoot默認會加載并讀取該配置,當發現為profile=dev時,會同時關聯加載application-dev.properties這個配置。
這種方式非常簡單,可以實現對不同環境采用單獨的配置文件進行隔離。
Maven本身也提供了Profile的功能,可以通過Maven的Profile配置來指定Spring的Profile。
這種做法稍微有點復雜,需要先在pom.xml中設定不同的 maven profile,如下:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>
這里,分別聲明了dev和prod兩個profile,每個profile都包含了一個spring.profiles.active屬性,這個屬性用來注入到 Spring中的profile入參。
在SpringBoot的配置文件application.properties中,需要替換為這個maven傳入的property:
## 使用Maven的屬性進行替換
spring.profiles.active=@spring.profiles.active@
接下來,需要讓Maven在打包時能將application.properties進行過濾處理,同時替換掉變量,需編輯pom.xml如下:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
這里定義了filtering=true,因此Resource打包插件會對配置文件執行過濾。
如果你的項目pom定義繼承自 spring-boot-starter-parent,那么可以不需要配置這個filter
最后,在maven打包時指定參數如下:
mvn clean package -Pprod
@ActiveProfile 是用于單元測試場景的注解,可以為測試代碼指定一個隔離的profile,如下:
@ActiveProfiles("test")
public void ApiTest{
...
}
ConfigurableEnvironment 這個Bean封裝了當前環境的配置信息,你可以在啟動應用前進行設定操作:
SpringApplication application = new SpringApplication(MyApplication.class);
//設置environment中的profiler
ConfigurableEnvironment environment = new StandardEnvironment();
environment.setActiveProfiles("dev","join_dev");
application.setEnvironment(environment);
application.run(args)
SpringApplication這個類還提供了setAdditionalProfiles方法,用來讓我們實現"附加"式的profile。
這些profile會同時被啟用,而不是替換原來的active profile,如下:
SpringApplication application = new SpringApplication(MyApplication.class);
application.setAdditionalProfiles("new_dev");
這種方式可以實現無條件的啟用profile,優先級是最高的。
當然,還可以通過設定spring.profiles.include來達到同樣的目的。
至此,我們已經提供了很多種方法來設定 Spring應用的profile,當它們同時存在時則會根據一定優先級來抉擇,參考如下:
從上至下,優先級從高到低排列。
其中,Maven profile與配置文件的方式相同,環境變量以及JVM啟動參數會覆蓋配置文件的內容。
1和2則屬于進程內的控制邏輯,優先級更高。
如果在啟動SpringBoot應用前對當前ConfigurableEnvironment對象注入了profile,則會優先使用這個參數, ActiveProfiles用于測試環境,其原理與此類似。
SpringApplication.setAdditionalProfiles則是無論如何都會附加的profile,優先級最高。
最后,我們在SpringBoot中演示一個使用Profile的例子。
一般,在開發環境和生產環境中的數據源配置是不同的,借助Profile我們可以定義出不同環境的數據源Bean。
首先我們先創建一個接口:
public interface DatasourceConfig {
public void setup();
}
對于開發環境,DatasourceConfig實現如下:
@Component
@Profile("dev")
public class DevDatasourceConfig implements DatasourceConfig {
@Override
public void setup() {
System.out.println("Setting up datasource for DEV environment. ");
}
}
同樣,為生產環境也實現一個DatasourceConfig:
@Component
@Profile("production")
public class ProductionDatasourceConfig implements DatasourceConfig {
@Override
public void setup() {
System.out.println("Setting up datasource for PRODUCTION environment. ");
}
}
接下來,我們聲明一個Bean,對數據源執行初始化方法:
@Component
public class SpringProfilesTest {
@Autowired
DatasourceConfig datasourceConfig;
@PostConstruct
public void setupDatasource() {
datasourceConfig.setup();
}
}
之后,在application.properties的配置為:
spring.profiles.active=dev
啟動SpringBoot 應用,發現輸出如下:
Setting up datasource for DEV environment.
此時說明dev的profile被啟用了!
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html
http://dolszewski.com/spring/spring-boot-properties-per-maven-profile/
https://www.concretepage.com/spring-5/activeprofiles-example-spring-test
https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/run-profiles.html
點擊查看美碼師的 SpringBoot 補習系列
如果喜歡我的文章,可關注美碼師的個人公眾號,筆者是十年老兵一枚,歡迎留言打擾,話題不限于技術、職場或生活..
"寫一首代碼,做一手好菜",當技術與美走到一起時,生活也可以是詩和遠方
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。