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

解決@Value注解不能注入static修飾的屬性問題

 更新時間:2022年07月08日 14:18:38   作者:iiaythi  
這篇文章主要介紹了解決@Value注解不能注入static修飾的屬性問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

@Value注解不能注入static屬性

問題描述

在application.yml中:

constant:
? key: hello
? value: world

工具類ConstantHelper:

@Component
public class ConstantHelper {
? ? @Value("${constant.value}")
? ? private static String value;
? ? private static String key;
? ? public static String getValue() {
? ? ? ? return value;
? ? }
? ? public void setValue(String value) {
? ? ? ? ConstantHelper.value = value;
? ? }
? ? public static String getKey() {
? ? ? ? return key;
? ? }
? ? @Value("${constant.key}")
? ? public void setKey(String key) {
? ? ? ? ConstantHelper.key = key;
? ? }
}

測試類:

@RequestMapping("/getConfig")
public Map<String, Object> getConfig(){
? ? Map<String,Object> map = new HashMap<>();
? ? map.put("key", ConstantHelper.getKey());
? ? map.put("value",ConstantHelper.getValue());
? ? return map;
}

結(jié)果:

{
    "value": null,
    "key": "hello"
}

可以發(fā)現(xiàn),@Value注解放在屬性上注入值失敗,而@Value放在setter方法上(注意,該方法也不能是靜態(tài)方法)卻能注入成功。為什么??

剖析

答案就在AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata方法中,AutowiredAnnotationBeanPostProcessor主要處理了@Autowired和@Value注解等等:

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
?? ??? ?List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
?? ??? ?Class<?> targetClass = clazz;
?? ??? ?do {
?? ??? ??? ?final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
?? ??? ??? ?ReflectionUtils.doWithLocalFields(targetClass, field -> {
?? ??? ??? ??? ?AnnotationAttributes ann = findAutowiredAnnotation(field);
?? ??? ??? ??? ?if (ann != null) {
? ? ? ? ? //here!!
?? ??? ??? ??? ??? ?if (Modifier.isStatic(field.getModifiers())) {
?? ??? ??? ??? ??? ??? ?if (logger.isInfoEnabled()) {
?? ??? ??? ??? ??? ??? ??? ?logger.info("Autowired annotation is not supported on static fields: " + field);
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?return;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?boolean required = determineRequiredStatus(ann);
?? ??? ??? ??? ??? ?currElements.add(new AutowiredFieldElement(field, required));
?? ??? ??? ??? ?}
?? ??? ??? ?});
?? ??? ??? ?ReflectionUtils.doWithLocalMethods(targetClass, method -> {
?? ??? ??? ??? ?Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
?? ??? ??? ??? ?if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
?? ??? ??? ??? ??? ?return;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
?? ??? ??? ??? ?if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
? ? ? ? ? //here!!
?? ??? ??? ??? ??? ?if (Modifier.isStatic(method.getModifiers())) {
?? ??? ??? ??? ??? ??? ?if (logger.isInfoEnabled()) {
?? ??? ??? ??? ??? ??? ??? ?logger.info("Autowired annotation is not supported on static methods: " + method);
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?return;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?if (method.getParameterCount() == 0) {
?? ??? ??? ??? ??? ??? ?if (logger.isInfoEnabled()) {
?? ??? ??? ??? ??? ??? ??? ?logger.info("Autowired annotation should only be used on methods with parameters: " +
?? ??? ??? ??? ??? ??? ??? ??? ??? ?method);
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?boolean required = determineRequiredStatus(ann);
?? ??? ??? ??? ??? ?PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
?? ??? ??? ??? ??? ?currElements.add(new AutowiredMethodElement(method, required, pd));
?? ??? ??? ??? ?}
?? ??? ??? ?});
?? ??? ??? ?elements.addAll(0, currElements);
?? ??? ??? ?targetClass = targetClass.getSuperclass();
?? ??? ?}
?? ??? ?while (targetClass != null && targetClass != Object.class);
?? ??? ?return new InjectionMetadata(clazz, elements);
?? ?}

The conceptual problem here is that annotation-driven injection happens for each bean instance. So we shouldn’t inject static fields or static methods there because that would happen for every instance of that class. The injection lifecycle is tied to the instance lifecycle, not to the class lifecycle. Bridging between an instance’s state and static accessor - if really desired - is up to the concrete bean implementation but arguably shouldn’t be done by the framework itself.

從源碼上發(fā)現(xiàn),理論上spring是可以對靜態(tài)域注入的,只是spring沒有這樣做,它認(rèn)為依賴注入發(fā)生的時段是在實例的生命周期,而不是類的生命周期

@Value(“${屬性}“)注入被static修飾的屬性

場景:

通過httpclient調(diào)用第三方接口的時候,ip和端口不確定

需求:

寫一個工具類,可以動態(tài)配置ip和端口來修改調(diào)用的地址和端口,要求工具類方法可以靜態(tài)調(diào)用。

問題描述

 static 不能和注解并用,被static修飾的成員變量,無法通過@Value注解動態(tài)獲取到

解決方案

通過注入到set方法實現(xiàn)屬性動態(tài)賦值

application.yml配置:

key:
? box:
? ? ip: 192.168.1.166
? ? port: 9987

錯誤代碼:

@Value("${key.box.ip}")
private static String ip ;
@Value("${key.box.port}")
private static String port;

這樣寫的話,你會發(fā)現(xiàn)拿到的結(jié)果還是null

正確代碼:

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
 * Created in 2021/6/29 15:07
 * @author 
 */
@Slf4j
@Component
public class KeyBoxHttpClientUtil {
    private static String ip ;
    private static String port;
    @Value("${key.box.ip}")
    public void setIP(String ip) {
        KeyBoxHttpClientUtil.ip = ip;
    }
    @Value("${key.box.port}")
    public void setPort(String port) {
        KeyBoxHttpClientUtil.port = port;
    }
}

Tips:調(diào)整代碼之后,工具類必須使用@Component注解來修飾,否則依然無法獲取到結(jié)果。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入理解Java中的克隆

    深入理解Java中的克隆

    想必大家對克隆都有耳聞,世界上第一只克隆羊多莉就是利用細(xì)胞核移植技術(shù)將哺乳動物的成年體細(xì)胞培育出新個體,甚為神奇。其實在Java中也存在克隆的概念,即實現(xiàn)對象的復(fù)制。本文將嘗試介紹一些關(guān)于Java中的克隆和一些深入的問題,希望可以幫助大家更好地了解克隆。
    2016-08-08
  • Mybatis打印替換占位符后的完整Sql教程

    Mybatis打印替換占位符后的完整Sql教程

    這篇文章主要介紹了Mybatis打印替換占位符后的完整Sql教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 淺談java異常鏈與異常丟失

    淺談java異常鏈與異常丟失

    下面小編就為大家?guī)硪黄獪\談java異常鏈與異常丟失。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • java.lang.IncompatibleClassChangeError異常的問題解決

    java.lang.IncompatibleClassChangeError異常的問題解決

    本文主要介紹了java.lang.IncompatibleClassChangeError異常的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Java數(shù)組隊列概念與用法實例分析

    Java數(shù)組隊列概念與用法實例分析

    這篇文章主要介紹了Java數(shù)組隊列概念與用法,結(jié)合實例形式分析了Java數(shù)組隊列相關(guān)概念、原理、用法及操作注意事項,需要的朋友可以參考下
    2020-03-03
  • JFinal 調(diào)用存儲過程的步驟

    JFinal 調(diào)用存儲過程的步驟

    這篇文章主要介紹了JFinal 調(diào)用存儲過程的步驟,幫助大家更好的理解和學(xué)習(xí)使用JFinal,感興趣的朋友可以了解下
    2021-03-03
  • Java 中的FileReader和FileWriter源碼分析_動力節(jié)點Java學(xué)院整理

    Java 中的FileReader和FileWriter源碼分析_動力節(jié)點Java學(xué)院整理

    本文給大家分享一段示例程序,通過示例代碼可以看出FileReader是基于InputStreamReader實現(xiàn)的,FileWriter是基于OutputStreamWriter實現(xiàn)的,具體程序代碼大家通過本文了解下吧
    2017-05-05
  • SpringBoot項目中忽略某屬性返回數(shù)據(jù)給前端

    SpringBoot項目中忽略某屬性返回數(shù)據(jù)給前端

    在Spring Boot中,保護(hù)敏感信息和減少數(shù)據(jù)傳輸是很重要的,我們可以使用多種方法來忽略返回數(shù)據(jù)中的字段,無論是使用@JsonIgnore注解、Projection投影、@JsonIgnoreProperties注解還是自定義序列化器,都能達(dá)到我們的目的,在實際應(yīng)用中,根據(jù)具體場景和需求選擇合適的方法
    2024-05-05
  • springboot hazelcast緩存中間件的實例代碼

    springboot hazelcast緩存中間件的實例代碼

    這篇文章主要介紹了springboot hazelcast緩存中間件的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • javaweb實戰(zhàn)之商城項目開發(fā)(一)

    javaweb實戰(zhàn)之商城項目開發(fā)(一)

    這篇文章主要針對javaweb商城項目開發(fā)進(jìn)行實戰(zhàn)演習(xí),對javaweb商城項目開發(fā)進(jìn)行詳細(xì)分析,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-02-02

最新評論

宁强县| 遂溪县| 托克逊县| 抚州市| 砀山县| 新乡县| 绍兴市| 象山县| 军事| 西平县| 长治县| 兖州市| 宁安市| 崇阳县| 澄城县| 连平县| 福海县| 鲜城| 玉山县| 郯城县| 商水县| 兴义市| 长治市| 静乐县| 达拉特旗| 寿阳县| 云林县| 筠连县| 临沧市| 绵阳市| 休宁县| 衢州市| 双牌县| 望奎县| 宣化县| 从江县| 东乌珠穆沁旗| 阳春市| 大城县| 平湖市| 团风县|