@Value注解给静态变量赋值的解决办法及原理探究
最近尝试通过读取配置⽂件中的配置,给某个类的静态变量赋值,发现居然没有成功,然后才知道原来是不⽀持给静态变量赋值的,解决办法就是将这个注解标注到实例⽅法上⾯,但是我们不仅要知道怎么做,还要知道为什么才⾏!
案例复现
配置⽂件内容
注: 我这个eclipseSE版本的,对springboot⽀持不够好,这个yml需要下载插件能变⾊,不过eclipse的下载插件也不太⽅便,就没搞了,不过这⾥不影响我使⽤。
配置类
package fig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Config {
@Value("${love}")
public static String love;
public void setLove(String love){
Config.love = love;
}
public String getLove(){
return love;
}
}
测试类
package fig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Config {
@Value("${love}")
public static String love;
public void setLove(String love){
Config.love = love;
}
public String getLove(){
return love;
}
}
测试结果
无线局域网密码这⾥预期⼀个字符串,但是结果是null,说明注⼊失败。查看SpringBoot的⽇志可以看到了,如下报错信息:Autowired annotation is not supported on static fields
2020-12-1020:20:12.224 INFO 12492---[ main]
f.a.AutowiredAnnotationBeanPostProcessor :
Autowired annotation is not supported on static fields:
public static java.lang.String fig.Config.love
查看源码,可以看到如下⽅法,其中会判断修饰符是否是static。如果是的话,则打印出上⾯那条⽇志。
如何解决呢?
通过上⾯的分析,可以看到确实@Value注解是不⽀持静态变量的,那么怎么解决呢?答案是需要 有对象!
解决⽅法
修改Config类,将@Value注解标注于setLove⽅法上,测试类不变,再次测试。
package fig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component高中班级工作总结
public class Config {
public static String love;
@Value("${love}")
public void setLove(String love){
Config.love = love;
}
public String getLove(){
return love;
}
}
测试成功
开车怎么起步这⾥可以看出,只需要将@Value⽅法标注到⽅法上即可,前提是这个⽅法必须是实例⽅法,并且它要
是赋值⽅法才⾏。(名字随意起,但是参数不能少!)
实际上这个注解可以修饰变量、⽅法、⽅法参数、注解上⾯!
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
离婚协议书范文2013@Documented
public @interface Value {
/**
* The actual value expression such as <code>#{Prop}</code>
* or property placeholder such as <code>${Prop}</code>.
*/
String value();
}
上⾯只是解决⽅法,但是没有说为什么?
1.为什么不能放在静态变量上?
2.为什么可以放在实例⽅法上?
这⾥其实很简单,第⼀个问题是代码本⾝不允许,第⼆个问题是因为Config这个类会产⽣⼀个对象。这⾥你可能会疑惑,我根本没有创建对象,也没有使⽤@Autowired注⼊Config对象呀?
如果你有疑问,那你因为你的基础没有学好,@Conpoment这个注解表⽰该类会交给Spring进⾏管理,所以实际上是Spring会帮我们创建⼀个Config对象,那创建对象的时候,不久顺便把@Value⽅法处理了嘛,所以赋值成功了,所以实际上就是对对象的变量进⾏赋值。
⽽且,@Autowired的作⽤是注⼊,并不是创建对象,对象是在这之前创建的!
再次测试初中数学手抄报
修改代码如下:
Config类添加⼀个空的构造⽅法,并且加⼊⼀个println语句;测试类不变。
这⾥可以忽略掉这个static块,我只是想测试⼀下它和构造器的执⾏顺序问题,
与这篇⽂章没有关系。
package fig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Config {
public static String love;
public Config(){
System.out.println("你好,我是Config类,我被创建对象了。");
}
static{
System.out.println("你好,我是Config类,我被初始化了。");
}
@Value("${love}")
public void setLove(String love){
Config.love = love;
}
public String getLove(){
return love;
}
}
再次测试
可以看到程序执⾏了构造器⾥⾯的⽅法,说明Config对象被创建了!
注:
1.Spring会帮助我们管理Bean,所以会通过构造器创建对象。
2.static块执⾏顺序在构造器之前,这个与这⾥⽆关。
再次修改代码
这⾥去掉了@Component注解,即不交给Spring管理我们的对象了,我们再来看⼀看结果如何?package fig;
import org.springframework.beans.factory.annotation.Value;
public class Config {
public static String love;
public Config(){
System.out.println("你好,我是Config类,我被创建对象了。");
电脑网络共享给手机}
static{
System.out.println("你好,我是Config类,我被初始化了。");
}
@Value("${love}")
public void setLove(String love){
Config.love = love;
}
public String getLove(){
return love;
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论