最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot @Conditional注解使用示例詳解

 更新時(shí)間:2024年12月31日 11:16:05   作者:山高自有客行路  
在SpringBoot中,@Conditional注解用于條件性地注冊(cè)bean,根據(jù)某些條件決定是否創(chuàng)建特定bean,可以實(shí)現(xiàn)Condition接口并重寫matches方法來(lái)定義條件,本文介紹Spring Boot @Conditional注解的相關(guān)知識(shí),感興趣的朋友一起看看吧

       在Spring Boot中,@Conditional 注解用于條件性地注冊(cè)bean。這意味著它可以根據(jù)某些條件來(lái)決定是否應(yīng)該創(chuàng)建一個(gè)特定的bean。這個(gè)注解可以放在配置類或方法上,并且它會(huì)根據(jù)提供的一組條件來(lái)判斷是否應(yīng)該實(shí)例化對(duì)應(yīng)的組件。

       要使用 @Conditional注解時(shí),需要實(shí)現(xiàn) Condition 接口并重寫 matches 方法。此方法將返回一個(gè)布爾值以指示條件是否匹配。如果條件為真,則創(chuàng)建bean;否則跳過(guò)該bean的創(chuàng)建。

以下是一個(gè)簡(jiǎn)單的例子,展示了如何使用自定義條件:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class MyCustomCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 在這里添加你的條件邏輯
        // 例如,檢查系統(tǒng)屬性、環(huán)境變量、已經(jīng)存在的beans等
        return false; // 根據(jù)條件邏輯返回true或false
    }
}
  • ConditionContext:提供了對(duì)當(dāng)前解析上下文的訪問(wèn),包括:
    • Environment:可以用來(lái)獲取環(huán)境變量、系統(tǒng)屬性等。
    • BeanFactory:如果可用的話,可以通過(guò)它訪問(wèn)已經(jīng)注冊(cè)的bean。
    • ClassLoader:可以用來(lái)檢查類路徑上的類是否存在。
    • EvaluationContext:可以用來(lái)評(píng)估SpEL表達(dá)式。
  • AnnotatedTypeMetadata 提供了對(duì)帶有注解的方法或類元數(shù)據(jù)的訪問(wèn),例如注解屬性值。

自定義條件類

假設(shè)我們有一個(gè)應(yīng)用程序,它應(yīng)該根據(jù)操作系統(tǒng)的不同來(lái)決定是否加載特定的bean。我們可以創(chuàng)建一個(gè)名為 OnWindowsCondition 的條件類:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class OnWindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return "win".equals(context.getEnvironment().getProperty("os.name").toLowerCase().substring(0, 3));
    }
}

然后在配置類中使用:

@Configuration
public class MyConfig {
    @Bean
    @Conditional(OnWindowsCondition.class)
    public WindowsSpecificService windowsSpecificService() {
        return new WindowsSpecificServiceImpl();
    }
}

Spring Boot提供內(nèi)置條件注解

@ConditionalOnProperty

當(dāng)你希望基于配置文件中的屬性是否存在或者具有特定值來(lái)創(chuàng)建bean時(shí),可以使用 @ConditionalOnProperty 注解。例如:

@Configuration
public class MyConfig {
    @Bean
    @ConditionalOnProperty(name = "my.feature.enabled", havingValue = "true")
    public MyFeature myFeature() {
        return new MyFeature();
    }
}

在這個(gè)例子中,只有當(dāng)配置文件中存在名為 my.feature.enabled 的屬性且其值為 true 時(shí),才會(huì)創(chuàng)建 MyFeature bean。

更多用法

  • prefix:指定屬性名前綴。
  • name:指定屬性名(可以是數(shù)組,表示多個(gè)屬性)。
  • havingValue:指定屬性必須具有的值,默認(rèn)為空字符串。
  • matchIfMissing:如果未找到屬性,則默認(rèn)匹配與否,默認(rèn)為 false

例如,你可以這樣配置:

@Bean
@ConditionalOnProperty(prefix = "app", name = "feature.enabled", havingValue = "true", matchIfMissing = false)
public FeatureService featureService() {
    return new FeatureServiceImpl();
}

這將確保只有在 app.feature.enabled=true 時(shí)才會(huì)創(chuàng)建 FeatureService bean;如果沒(méi)有設(shè)置該屬性且 matchIfMissing=false,則不會(huì)創(chuàng)建。

@ConditionalOnClass 和 @ConditionalOnMissingClass

這兩個(gè)注解用于檢查類路徑下是否存在或不存在某些類。這在集成第三方庫(kù)時(shí)非常有用,因?yàn)槟憧梢杂袟l件地注冊(cè)與這些庫(kù)相關(guān)的bean。例如:

@Configuration
@ConditionalOnClass(name = "com.example.ExternalLibraryClass")
public class ExternalLibraryConfig {
    // ...
}

如果類路徑中存在 ExternalLibraryClass 類,則會(huì)應(yīng)用此配置。

@ConditionalOnBean 和 @ConditionalOnMissingBean

這些注解用于根據(jù)上下文中是否存在指定類型的bean來(lái)決定是否創(chuàng)建新的bean。這對(duì)于確保不會(huì)重復(fù)注冊(cè)相同功能的bean非常有用。

@Bean
@ConditionalOnMissingBean(MyService.class)
public MyService myService() {
    return new MyServiceImpl();
}

這里的意思是:如果上下文中還沒(méi)有類型為 MyService 的bean,則創(chuàng)建一個(gè)新的 MyServiceImpl 實(shí)例并注冊(cè)為bean。

使用 SpEL 表達(dá)式的 @ConditionalOnExpression

可以通過(guò) @ConditionalOnExpression 來(lái)編寫復(fù)雜的條件表達(dá)式。例如,基于多個(gè)屬性組合或者環(huán)境變量來(lái)決定是否創(chuàng)建bean。

@Bean
@ConditionalOnExpression("${spring.application.name:'default'} == 'myapp' && ${env:dev} == 'prod'")
public ProdSpecificBean prodSpecificBean() {
    return new ProdSpecificBean();
}

這段代碼意味著只有當(dāng)應(yīng)用程序名稱為 'myapp' 并且環(huán)境變量 env 設(shè)置為 'prod' 時(shí),才會(huì)創(chuàng)建 ProdSpecificBean。

使用場(chǎng)景

動(dòng)態(tài)條件評(píng)估

有時(shí)你可能需要在應(yīng)用啟動(dòng)后根據(jù)某些變化(如用戶輸入或外部服務(wù)的狀態(tài))來(lái)動(dòng)態(tài)調(diào)整bean的行為。雖然 @Conditional 主要用于啟動(dòng)時(shí)的靜態(tài)條件判斷,但你可以通過(guò)結(jié)合其他機(jī)制(如事件監(jiān)聽(tīng)器、定時(shí)任務(wù)等)來(lái)實(shí)現(xiàn)類似的效果。

@Configuration
public class DynamicConditionConfig {
    private final AtomicBoolean shouldCreateBean = new AtomicBoolean(false);
    @Bean
    @ConditionalOnProperty(name = "dynamic.bean.enabled", havingValue = "true")
    public MyDynamicBean myDynamicBean() {
        return () -> shouldCreateBean.get();
    }
    // 模擬外部觸發(fā)更新條件狀態(tài)的方法
    public void updateCondition(boolean value) {
        shouldCreateBean.set(value);
    }
}

在這個(gè)例子中,MyDynamicBean 的行為依賴于一個(gè)原子布爾變量 shouldCreateBean,該變量可以在運(yùn)行時(shí)被更改,從而影響bean的行為。

條件化的AOP切面

你還可以將條件應(yīng)用于AOP切面,以實(shí)現(xiàn)更加靈活的橫切關(guān)注點(diǎn)管理。例如:

@Aspect
@ConditionalOnProperty(name = "app.logging.enabled", havingValue = "true")
public class LoggingAspect {
    @Around("execution(* com.example.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long executionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + " executed in " + executionTime + "ms");
        return proceed;
    }
}

這段代碼表示只有當(dāng) app.logging.enabled=true 時(shí)才會(huì)激活日志記錄切面。

使用 @Profile 和 @Conditional 結(jié)合

有時(shí)候,你可能想要結(jié)合 @Profile@Conditional 來(lái)創(chuàng)建更精細(xì)的條件邏輯。例如:

@Configuration
@Profile("dev")
public class DevConfig {
    @Bean
    @ConditionalOnProperty(name = "feature.x.enabled", havingValue = "true")
    public FeatureX featureX() {
        return new FeatureXImpl();
    }
}

這里的意思是:僅在開(kāi)發(fā)環(huán)境(dev profile)并且 feature.x.enabled=true 時(shí)才創(chuàng)建 FeatureX bean。

條件化代理

對(duì)于那些需要延遲初始化或者懶加載的bean,可以考慮使用 @Scope("proxy")@Lazy 注解,結(jié)合 @Conditional 來(lái)實(shí)現(xiàn)條件化代理。

@Bean
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
@Lazy
@ConditionalOnProperty(name = "lazy.init.feature", havingValue = "true")
public LazyInitFeature lazyInitFeature() {
    return new LazyInitFeatureImpl();
}

這確保了只有在滿足條件且首次訪問(wèn) lazyInitFeature bean時(shí)才會(huì)實(shí)例化它。

調(diào)試技巧

使用 @PostConstruct 和 @PreDestroy 監(jiān)控bean生命周期

為了更好地理解哪些bean被創(chuàng)建或銷毀,可以在bean類中添加 @PostConstruct@PreDestroy 方法,并輸出日志信息。

@Component
@ConditionalOnProperty(name = "feature.y.enabled", havingValue = "true")
public class FeatureY {
    @PostConstruct
    public void init() {
        System.out.println("FeatureY initialized.");
    }
    @PreDestroy
    public void destroy() {
        System.out.println("FeatureY destroyed.");
    }
}

這種方法有助于跟蹤bean的生命周期,并確認(rèn)條件是否按預(yù)期工作。

使用 spring.main.banner-mode=off 減少干擾

當(dāng)你專注于調(diào)試條件邏輯時(shí),關(guān)閉Spring Boot啟動(dòng)橫幅可以幫助減少不必要的輸出,使日志更加清晰。

spring.main.banner-mode=off

常見(jiàn)問(wèn)題

環(huán)境屬性未正確加載

如果發(fā)現(xiàn)條件注解沒(méi)有按照預(yù)期工作,請(qǐng)檢查是否正確加載了環(huán)境屬性文件(如 application.propertiesapplication.yml)。確保這些文件位于正確的路徑下,并且包含所需的屬性定義。

類路徑?jīng)_突

當(dāng)遇到條件注解不起作用的問(wèn)題時(shí),類路徑?jīng)_突是一個(gè)常見(jiàn)的原因。特別是當(dāng)你使用 @ConditionalOnClass@ConditionalOnMissingClass 時(shí),確保項(xiàng)目中不存在重復(fù)的依賴項(xiàng)。你可以使用Maven或Gradle命令來(lái)分析依賴樹(shù):

Maven:

mvn dependency:tree

Gradle:

gradle dependencies

條件邏輯錯(cuò)誤

仔細(xì)審查你的條件邏輯,確保它們符合預(yù)期??梢酝ㄟ^(guò)單元測(cè)試驗(yàn)證每個(gè)條件的行為。例如:

@Test
void testFeatureYEnabled() {
    ApplicationContextRunner runner = new ApplicationContextRunner()
        .withPropertyValues("feature.y.enabled=true");
    runner.run(context -> assertThat(context).hasSingleBean(FeatureY.class));
}
@Test
void testFeatureYDisabled() {
    ApplicationContextRunner runner = new ApplicationContextRunner()
        .withPropertyValues("feature.y.enabled=false");
    runner.run(context -> assertThat(context).doesNotHaveBean(FeatureY.class));
}

注意事項(xiàng)

  • 條件注解只適用于Spring的配置階段,因此它們不能用于運(yùn)行時(shí)決策。
  • 當(dāng)使用 @Conditional 或其他條件注解時(shí),請(qǐng)確保你的條件邏輯不會(huì)導(dǎo)致循環(huán)依賴或意外的行為。
  • 在編寫條件邏輯時(shí),考慮到性能影響,盡量使條件判斷輕量級(jí)。

到此這篇關(guān)于Spring Boot @Conditional注解的文章就介紹到這了,更多相關(guān)Spring Boot @Conditional注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • resultMap標(biāo)簽中里的collection標(biāo)簽詳解

    resultMap標(biāo)簽中里的collection標(biāo)簽詳解

    這篇文章主要介紹了resultMap標(biāo)簽中里的collection標(biāo)簽,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • MyBatis中獲取Mysql數(shù)據(jù)庫(kù)插入記錄的主鍵值的實(shí)現(xiàn)

    MyBatis中獲取Mysql數(shù)據(jù)庫(kù)插入記錄的主鍵值的實(shí)現(xiàn)

    本文主要介紹了MyBatis中獲取Mysql數(shù)據(jù)庫(kù)插入記錄的主鍵值的實(shí)現(xiàn),包含了三種實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Java網(wǎng)絡(luò)編程之UDP網(wǎng)絡(luò)通信詳解

    Java網(wǎng)絡(luò)編程之UDP網(wǎng)絡(luò)通信詳解

    這篇文章主要為大家詳細(xì)介紹了Java網(wǎng)絡(luò)編程中的UDP網(wǎng)絡(luò)通信的原理與實(shí)現(xiàn),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-09-09
  • Java實(shí)戰(zhàn)之實(shí)現(xiàn)OA辦公管理系統(tǒng)

    Java實(shí)戰(zhàn)之實(shí)現(xiàn)OA辦公管理系統(tǒng)

    這篇文章主要介紹了如何通過(guò)Java實(shí)現(xiàn)OA辦公管理系統(tǒng),文章采用到了JSP、JQuery、Ajax等技術(shù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-02-02
  • springboot項(xiàng)目中引入本地依賴jar包并打包到lib文件夾中

    springboot項(xiàng)目中引入本地依賴jar包并打包到lib文件夾中

    這篇文章主要介紹了springboot項(xiàng)目中引入本地依賴jar包,如何打包到lib文件夾中,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • 淺談SpringMVC國(guó)際化支持

    淺談SpringMVC國(guó)際化支持

    這篇文章主要介紹了淺談SpringMVC國(guó)際化支持,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Spring Boot 2.0 整合 Spring Security OAuth2的完整實(shí)現(xiàn)方案

    Spring Boot 2.0 整合 Spring Security&

    OAuth 2.0是一個(gè)行業(yè)標(biāo)準(zhǔn)的授權(quán)協(xié)議,它允許用戶在不將用戶名和密碼提供給第三方應(yīng)用的情況下,授權(quán)第三方應(yīng)用訪問(wèn)用戶存儲(chǔ)在服務(wù)提供方的資源,本文給大家介紹Spring Boot 2.0 整合 Spring Security OAuth2的完整實(shí)現(xiàn)方案,感興趣的朋友一起看看吧
    2026-03-03
  • Spring Boot與Redisson實(shí)時(shí)排行榜功能

    Spring Boot與Redisson實(shí)時(shí)排行榜功能

    排行榜功能是常見(jiàn)且重要的需求之一,本文主要介紹了Spring Boot與Redisson實(shí)時(shí)排行榜功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • 實(shí)例分析Java單線程與多線程

    實(shí)例分析Java單線程與多線程

    本篇文章通過(guò)代碼實(shí)例給大家詳細(xì)講述了Java單線程與多線程的相關(guān)原理和知識(shí)點(diǎn)總結(jié),需要的朋友可以學(xué)習(xí)下。
    2018-02-02
  • 詳解Java項(xiàng)目中讀取properties文件

    詳解Java項(xiàng)目中讀取properties文件

    本篇文章主要介紹了Java項(xiàng)目中讀取properties文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-12-12

最新評(píng)論

新乡县| 平远县| 舒兰市| 新野县| 聂拉木县| 保德县| 丹阳市| 安庆市| 克东县| 密山市| 化德县| 中卫市| 洛浦县| 淅川县| 黄浦区| 桐庐县| 苗栗市| 西华县| 财经| 巴中市| 绥滨县| 都匀市| 江油市| 准格尔旗| 永平县| 含山县| 平凉市| 邵阳县| 渭南市| 金坛市| 新兴县| 尼勒克县| 瑞昌市| 习水县| 南丰县| 灵丘县| 玉山县| 罗山县| 石渠县| 吴堡县| 莆田市|