淺談關(guān)于spring profile的誤解
背景
spring的profile大家都是用的溜的飛起~
那么profile的組合如何使用呢???
比如我們這樣使用
@Profile({"prod", "unit-test"})
分析
上述的profile大家應(yīng)該不會(huì)存有疑問(wèn) 當(dāng)profile為prod或者unit-test的時(shí)候才會(huì)生效。
但是如果我們使用非呢~如何確保在某些情況下不生效!
spring提供了常見(jiàn)的!來(lái)進(jìn)行描述
因此如果想要在非生產(chǎn)環(huán)境生效只要簡(jiǎn)單的寫成
@Profile({"!prod"})
那么如何在多個(gè)環(huán)境下不生效呢???
自作聰明的某些人【我】如下代碼
@Profile({"!prod", "!unit-test"})
那么實(shí)際情況是否如此呢???
我們看一下對(duì)應(yīng)的代碼
代碼
profile是通過(guò)profileCondition來(lái)完成控制的
class ProfileCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (context.getEnvironment() != null) {
MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
if (attrs != null) {
for (Object value : attrs.get("value")) {
if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
return true;
}
}
return false;
}
}
return true;
}
}
很明顯可以看到了acceptsProfiles
/**
* Return whether one or more of the given profiles is active or, in the case of no
* explicit active profiles, whether one or more of the given profiles is included in
* the set of default profiles. If a profile begins with '!' the logic is inverted,
* i.e. the method will return true if the given profile is <em>not</em> active.
* For example, <pre class="code">env.acceptsProfiles("p1", "!p2")</pre> will
* return {@code true} if profile 'p1' is active or 'p2' is not active.
* @throws IllegalArgumentException if called with zero arguments
* or if any profile is {@code null}, empty or whitespace-only
* @see #getActiveProfiles
* @see #getDefaultProfiles
*/
boolean acceptsProfiles(String... profiles);
從上述可以看到應(yīng)該是or的條件
當(dāng)然代碼如下
@Override
public boolean acceptsProfiles(String... profiles) {
Assert.notEmpty(profiles, "Must specify at least one profile");
for (String profile : profiles) {
if (StringUtils.hasLength(profile) && profile.charAt(0) == '!') {
if (!isProfileActive(profile.substring(1))) {
return true;
}
}
else if (isProfileActive(profile)) {
return true;
}
}
return false;
}
因此可以看到當(dāng)是!條件的時(shí)候會(huì)判斷如果當(dāng)前未激活profile返回true 否則當(dāng)前是正常條件的換當(dāng)前profile如果激活則返回true 當(dāng)上述條件都不滿足才返回false
因此上述邏輯告訴我們其實(shí)應(yīng)該是或者的邏輯。因此
@Profile({"!prod", "!unit-test"})
!prod||!unit-test===>!(prod&&unit-test) 也就是說(shuō)當(dāng)prod和unit-test都生效的時(shí)候才不會(huì)注冊(cè) 其他調(diào)均都會(huì)注冊(cè)生效
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java StampedLock實(shí)現(xiàn)原理與最佳實(shí)踐記錄
本文介紹了Java 8引入的StampedLock,這是一種多模式同步控制組件,通過(guò)“戳”(stamp)標(biāo)識(shí)鎖的狀態(tài),支持寫鎖、悲觀讀鎖和樂(lè)觀讀三種模式,StampedLock在特定場(chǎng)景下能夠大幅提升系統(tǒng)性能,特別是在讀多寫少的場(chǎng)景中,感興趣的朋友跟隨小編一起看看吧2025-01-01
Spring中@Transactional用法詳細(xì)介紹
這篇文章主要介紹了Spring中@Transactional用法詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-02-02
整理java讀書(shū)筆記十五之java中的內(nèi)部類
內(nèi)部類是指在一個(gè)外部類的內(nèi)部再定義一個(gè)類。類名不需要和文件夾相同。本文給大家分享java讀書(shū)筆記十五之java中的內(nèi)部類,對(duì)java讀書(shū)筆記相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2015-12-12
SpringBoot+RabbitMQ實(shí)現(xiàn)消息可靠傳輸詳解
消息的可靠傳輸是面試必問(wèn)的問(wèn)題之一,保證消息的可靠傳輸主要在生產(chǎn)端開(kāi)啟?comfirm?模式,RabbitMQ?開(kāi)啟持久化,消費(fèi)端關(guān)閉自動(dòng)?ack?模式。本文將詳解SpringBoot整合RabbitMQ如何實(shí)現(xiàn)消息可靠傳輸,需要的可以參考一下2022-05-05
Java中Lombok工具庫(kù)使用的技術(shù)指南
Lombok 是 Java 開(kāi)發(fā)中常用的工具庫(kù),通過(guò)注解的方式大大簡(jiǎn)化了代碼開(kāi)發(fā),本篇文章將從基礎(chǔ)入門到高級(jí)用法,深入講解 Lombok 的使用技巧和注意事項(xiàng),快跟隨小編一起來(lái)學(xué)習(xí)一下吧2025-04-04
springboot-jpa的實(shí)現(xiàn)操作
這篇文章主要介紹了springboot-jpa的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03

