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

SpringBoot之@ConditionalOnProperty注解使用方法

 更新時間:2023年05月05日 11:21:11   作者:搶老婆酸奶的小肥仔  
在平時業(yè)務(wù)中,我們需要在配置文件中配置某個屬性來決定是否需要將某些類進行注入,讓Spring進行管理,而@ConditionalOnProperty能夠?qū)崿F(xiàn)該功能,文中有詳細的代碼示例,需要的朋友可以參考下

@ConditionalOnProperty:根據(jù)屬性值來控制類或某個方法是否需要加載。它既可以放在類上也可以放在方法上。

1、SpringBoot實現(xiàn)

1.1 設(shè)置配置屬性

在applicatio.properties或application.yml配置isload_bean = true;

#配置是否加載類
is_load_bean: true

1.2 編寫加載類

編寫加載類,使用@Component進行注解,為了便于區(qū)分,我們將@ConditionalOnProperty放在方法上。

/**
 * @author: jiangjs
 * @description: 使用@ConditionalOnProperty
 * @date: 2023/4/24 10:20
 **/
@Component
@Slf4j
public class UseConditionalOnProperty {

    @Value("${is_load_bean}")
    private String isLoadBean;

    @Bean
    @ConditionalOnProperty(value = "is_load_bean",havingValue = "true",matchIfMissing = true)
    public void loadBean(){
        log.info("是否加載當(dāng)前類");
    }

    @Bean
    public void compareLoadBean(){
        log.info("加載bean屬性:" + isLoadBean);
    }
}

啟動項目時輸出打印的日志。如圖:

將配置文件的數(shù)據(jù)信息改成false,則不會打印出結(jié)果。

2、ConditionalOnProperty屬性與源碼

2.1 屬性

查看@ConditionalOnProperty源碼可以看到該注解定義了幾個屬性。

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {

	/**
	 * name別名,數(shù)組類型,獲取對應(yīng)property名稱的值,與name不能同時使用
	 */
	String[] value() default {};

	/**
	 * 屬性前綴,未指定時,自動以點"."結(jié)束,有效前綴由一個或多個詞用點"."連接。
     * 如:spring.datasource
	 */
	String prefix() default "";

	/**
	 * 屬性名稱,配置屬性完整名稱或部分名稱,可與prefix組合使用,不能與value同時使用
	 */
	String[] name() default {};

	/**
	 * 可與name組合使用,比較獲取到的屬性值與havingValue的值是否相同,相同才加載配置
	 */
	String havingValue() default "";

	/**
	 * 缺少該配置屬性時是否加載,默認(rèn)為false。如果為true,沒有該配置屬性時也會正常加載;反之則不會生效
	 */
	boolean matchIfMissing() default false;

}

2.2 源碼

查看OnPropertyCondition類中國的getMatchOutcome()方法:

@Override
	public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
		//獲取所有注解ConditionalOnProperty下的所有屬性match,message
        List<AnnotationAttributes> allAnnotationAttributes = annotationAttributesFromMultiValueMap(
				metadata.getAllAnnotationAttributes(ConditionalOnProperty.class.getName()));
		List<ConditionMessage> noMatch = new ArrayList<>();
		List<ConditionMessage> match = new ArrayList<>();
        //遍歷注解中的屬性
		for (AnnotationAttributes annotationAttributes : allAnnotationAttributes) {
            //創(chuàng)建判定的結(jié)果,ConditionOutcome只有兩個屬性,
			ConditionOutcome outcome = determineOutcome(annotationAttributes, context.getEnvironment());
			(outcome.isMatch() ? match : noMatch).add(outcome.getConditionMessage());
		}
		if (!noMatch.isEmpty()) {
            //如果有屬性沒有匹配,則返回
			return ConditionOutcome.noMatch(ConditionMessage.of(noMatch));
		}
		return ConditionOutcome.match(ConditionMessage.of(match));
	}

在上述源碼中determineOutcome()是關(guān)鍵方法,我們來看看:

private ConditionOutcome determineOutcome(AnnotationAttributes annotationAttributes, PropertyResolver resolver) {
	//初始化
    Spec spec = new Spec(annotationAttributes);
    List<String> missingProperties = new ArrayList<>();
    List<String> nonMatchingProperties = new ArrayList<>();
    //收集屬性,將結(jié)果賦值給missingProperties,nonMatchingProperties
    spec.collectProperties(resolver, missingProperties, nonMatchingProperties);
    if (!missingProperties.isEmpty()) {
        //missingProperties屬性不為空,說明設(shè)置matchIfMissing的是false,則不加載類
        return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, spec)
                .didNotFind("property", "properties").items(Style.QUOTE, missingProperties));
    }
    if (!nonMatchingProperties.isEmpty()) {
        //nonMatchingProperties屬性不為空,則設(shè)置的屬性值與havingValue值不匹配,則不加載類
        return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, spec)
                .found("different value in property", "different value in properties")
                .items(Style.QUOTE, nonMatchingProperties));
    }
    return ConditionOutcome
            .match(ConditionMessage.forCondition(ConditionalOnProperty.class, spec).because("matched"));
}

Spec是OnPropertyCondition的一個靜態(tài)內(nèi)部類,初始化@ConditionalOnProperty中的屬性。

private static class Spec {

		private final String prefix;

		private final String havingValue;

		private final String[] names;

		private final boolean matchIfMissing;
        //初始化,給各屬性賦值
		Spec(AnnotationAttributes annotationAttributes) {
			String prefix = annotationAttributes.getString("prefix").trim();
			if (StringUtils.hasText(prefix) && !prefix.endsWith(".")) {
				prefix = prefix + ".";
			}
			this.prefix = prefix;
			this.havingValue = annotationAttributes.getString("havingValue");
			this.names = getNames(annotationAttributes);
			this.matchIfMissing = annotationAttributes.getBoolean("matchIfMissing");
		}

        //處理name與value
		private String[] getNames(Map<String, Object> annotationAttributes) {
			String[] value = (String[]) annotationAttributes.get("value");
			String[] name = (String[]) annotationAttributes.get("name");
            //限制了value或name必須指定
			Assert.state(value.length > 0 || name.length > 0,
					"The name or value attribute of @ConditionalOnProperty must be specified");
			//value和name只能有一個存在,不能同時使用
            Assert.state(value.length == 0 || name.length == 0,
					"The name and value attributes of @ConditionalOnProperty are exclusive");
            return (value.length > 0) ? value : name;
		}

		private void collectProperties(PropertyResolver resolver, List<String> missing, List<String> nonMatching) {
			//遍歷names,即value或name的值
            for (String name : this.names) {
                //前綴 + name,獲取配置文件中key
				String key = this.prefix + name;
                //驗證配置屬性中包含key
				if (resolver.containsProperty(key)) {
                    //如包含,則獲取key對應(yīng)的值,與havingValue的值進行匹配
					if (!isMatch(resolver.getProperty(key), this.havingValue)) {
                        //不匹配則添加到nonMatching
						nonMatching.add(name);
					}
				}
				else {
                    //驗證配置屬性中沒有包含key,判斷是否配置了matchIfMissing屬性
					if (!this.matchIfMissing) {
                        //該屬性不為true則添加到missing中
						missing.add(name);
					}
				}
			}
		}

		private boolean isMatch(String value, String requiredValue) {
            //驗證requiredValue是否有值
			if (StringUtils.hasLength(requiredValue)) {
                //有值,則進行比較,不區(qū)分大小寫
				return requiredValue.equalsIgnoreCase(value);
			}
            //沒有值,則驗證value是否等于false
            //這也是為什么name, value不配置值的情況下, 類依然會被加載的原因
			return !"false".equalsIgnoreCase(value);
		}

		@Override
		public String toString() {
			StringBuilder result = new StringBuilder();
			result.append("(");
			result.append(this.prefix);
			if (this.names.length == 1) {
				result.append(this.names[0]);
			}
			else {
				result.append("[");
				result.append(StringUtils.arrayToCommaDelimitedString(this.names));
				result.append("]");
			}
			if (StringUtils.hasLength(this.havingValue)) {
				result.append("=").append(this.havingValue);
			}
			result.append(")");
			return result.toString();
		}

	}

根據(jù)業(yè)務(wù)需求,我們可以實現(xiàn)配置某些屬性動態(tài)地去加載某些類或方法。

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

相關(guān)文章

  • Java單例模式簡單示例

    Java單例模式簡單示例

    這篇文章主要介紹了Java單例模式,結(jié)合實例形式簡單分析了java單例模式的定義與使用技巧,需要的朋友可以參考下
    2017-06-06
  • SpringBoot中使用RocketMQ的示例代碼

    SpringBoot中使用RocketMQ的示例代碼

    本文主要介紹SpringBoot中使用RocketMQ的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java拋出異常與自定義異常類應(yīng)用示例

    Java拋出異常與自定義異常類應(yīng)用示例

    這篇文章主要介紹了Java拋出異常與自定義異常類,結(jié)合實例形式分析了Java針對錯誤與異常處理的try、catch、throw等語句相關(guān)使用技巧,需要的朋友可以參考下
    2019-03-03
  • druid?handleException執(zhí)行流程源碼解析

    druid?handleException執(zhí)行流程源碼解析

    這篇文章主要為大家介紹了druid?handleException執(zhí)行流程源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • springboot2整合redis使用lettuce連接池的方法(解決lettuce連接池?zé)o效問題)

    springboot2整合redis使用lettuce連接池的方法(解決lettuce連接池?zé)o效問題)

    這篇文章主要介紹了springboot2整合redis使用lettuce連接池(解決lettuce連接池?zé)o效問題),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • SpringBoot?整合?Grizzly的過程

    SpringBoot?整合?Grizzly的過程

    Grizzly?是一個高性能的、異步的、非阻塞的?HTTP?服務(wù)器框架,它可以與?Spring?Boot?一起提供比傳統(tǒng)的?Tomcat?或?Jetty?更高的吞吐量和更低的延遲,這篇文章主要介紹了SpringBoot?整合?Grizzly的過程,需要的朋友可以參考下
    2025-01-01
  • Java如何調(diào)用HTTP接口

    Java如何調(diào)用HTTP接口

    本文介紹了Java調(diào)用HTTP接口的方法,包括使用HttpURLConnection和HttpClient工具,作者分享了個人經(jīng)驗,并鼓勵讀者參考和支持
    2025-01-01
  • SpringBoot使用RestTemplate發(fā)送http請求的實操演示

    SpringBoot使用RestTemplate發(fā)送http請求的實操演示

    RestTemplate是Spring 框架提供的 ,可用于在應(yīng)用中調(diào)用 rest 服務(wù),它簡化了與 http 服務(wù)的通信方式,統(tǒng)一了 RESTful 的標(biāo)準(zhǔn),封裝了 http 鏈接,本文給大家介紹了SpringBoot使用RestTemplate發(fā)送http請求的實操演示,需要的朋友可以參考下
    2024-11-11
  • 解析Mybatis判斷表達式源碼分析

    解析Mybatis判斷表達式源碼分析

    這篇文章主要介紹了Mybatis判斷表達式源碼分析,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-10-10
  • Java中在控制臺讀取字符的實現(xiàn)示例

    Java中在控制臺讀取字符的實現(xiàn)示例

    Scanner是Java中的一個類,可以用于讀取控制臺輸入,通過Scanner對象可以方便地從控制臺讀取數(shù)字或字符串,本文就來介紹一下Java中在控制臺讀取字符的實現(xiàn)示例,感興趣的可以了解一下
    2023-10-10

最新評論

孟津县| 调兵山市| 梓潼县| 方正县| 阿坝县| 新田县| 四子王旗| 上饶县| 平果县| 阳原县| 开封市| 拜泉县| 镶黄旗| 噶尔县| 乡宁县| 措勤县| 蓝田县| 松阳县| 安图县| 永丰县| 栾川县| 泾源县| 孟州市| 林口县| 甘洛县| 历史| 鸡西市| 洪江市| 莱州市| 平武县| 鲁甸县| 鄂州市| 闽侯县| 安国市| 出国| 南阳市| 威宁| 布拖县| 舟曲县| 汕尾市| 清远市|