@value注解 static,修改注解的value值

  @value注解 static,修改注解的value值

  

目录

@值注解不能注入静电属性问题描述剖析@Value("${属性}")注入被静电修饰的属性问题描述解决方案

 

  

@Value注解不能注入static属性

 

  

问题描述

在应用程序.阳明海运股份有限公司中:

 

  常量:键:你好值:世界工具类康斯坦特勒:

  @ component公共类常量帮助器{ @ Value( $ { constant。值} )私有静态字符串值;私有静态字符串密钥;公共静态字符串getValue() {返回值;} public void setValue(String value){ constant helper。值=值;}公共静态字符串getKey(){ return key;} @ Value( $ {常量。key } )public void setKey(String key){ constant helper。key=key}}测试类:

  @ request mapping(/getConfig )public MapString,Object getConfig(){ MapString,Object map=new HashMap();map.put(key ,常量助手。getkey());map.put(value ,常量帮助器。getvalue());返回地图;}结果:

  { value: null, key: hello}

  可以发现,@值注解放在属性上注入值失败,而@值放在作曲者方法上(注意,该方法也不能是静态方法)却能注入成功。为什么?

  

剖析

答案就在AutowiredAnnotationBeanPostProcessor # buildAutowiringMetadata方法中,AutowiredAnnotationBeanPostProcessor主要处理了@自动连线和@值注解等等:

 

  私有注入元数据buildAutowiringMetadata(最终类?{ ListInjectionMetadata .注入的元素elements=new ArrayList();班级?target class=clazzdo { final ListInjectionMetadata .注入元素curr elements=new ArrayList();反射工具。dowithlocalfields(目标类,field-{ AnnotationAttributes ann=findAutowiredAnnotation(field));如果(安!=null){//这里!if(修饰语。是静态的(字段。get modifiers()){ if(logger。isinfoenabled()){ logger。信息(静态字段: 字段不支持自动连线批注);}

       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.

 

  

从源码上发现,理论上spring是可以对静态域注入的,只是spring没有这样做,它认为依赖注入发生的时段是在实例的生命周期,而不是类的生命周期

 

  

 

  

@Value(${属性})注入被static修饰的属性

场景:

 

  通过httpclient调用第三方接口的时候,ip和端口不确定

  需求:

  写一个工具类,可以动态配置ip和端口来修改调用的地址和端口,要求工具类方法可以静态调用。

  

问题描述

static 不能和注解并用,被static修饰的成员变量,无法通过@Value注解动态获取到

 

  

 

  

解决方案

通过注入到set方法实现属性动态赋值

 

  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;

这样写的话,你会发现拿到的结果还是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@Componentpublic 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:调整代码之后,工具类必须使用@Component注解来修饰,否则依然无法获取到结果。

 

  以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: