大佬们 请教一下关于 Spring 的 @Value 注解

2022-03-16 17:15:06 +08:00
 max58

我目前遇到的情况大概如下:

class Test{
    @Value("${xxxx}")
    private String a1;
    @Value("${xxxx}")
    private String a2;
    @Value("${xxxx}")
    private String a3;
    
    private Demo demo;
    public Test(){
        demo = Demo.builder(a1,a2,a3);
    }
}   

a1,a2,a3 是从公司的配置中心拉去的值 现在出现这种情况: 在启动项目加载的时候,只会加载 a1,a2,a3 并不会给赋值 导致注入 demo 的参数都是 null 个人认为 spring 在加载的时候会把对应的值拉取到然后赋予变量 有没有大佬明白,教一下菜鸡。

个人的解决办法:创建的一个 Config 类 能保证能够拉取到值然后完成注入

@Configuration
public class DemoConfig {

    @Value("${xxxx}")
    private String a1;
    @Value("${xxxx}")
    private String a2;
    @Value("${xxxx}")
    private String a3;

    @Bean
    public Demo bulid() throws MalformedURLException, SignatureException {
        return new Demo.Builder(a1,a2,a3);
    }
}
class Test{
 
    @Resource
    private Demo demo;
  
} 

2045 次点击
所在节点    Java
14 条回复
XhstormR02
2022-03-16 17:30:19 +08:00
Test 类的构造方法在 @Value 注入之前就调用了
max58
2022-03-16 17:33:20 +08:00
@XhstormR02 我之前还试过一种写法 在 成员字符串变量前加 static 和 不在构造方法中创建 直接去 new 也是不行的
bringyou
2022-03-16 17:42:31 +08:00
可以在 postcontruct (或者 InitializingBean 的 afterPropertiesSet )里面初始化 demo
xjngbla
2022-03-16 17:43:38 +08:00
楼主是在 controller 里使用的这个注解么
Kasumi20
2022-03-16 17:55:17 +08:00
为什么 Demo 不去存 Test 的引用
zzfer
2022-03-16 17:58:40 +08:00
@Value 注解必须再 spring 注解标注后的类(@Configuration,@Controller,@Service 等)才能起作用吧
BiChengfei
2022-03-16 18:03:33 +08:00
@Component
public class Test {

private Demo demo;

public Test(@Value("${demo.a1}") String a1,@Value("${demo.a2}") String a2,@Value("${demo.a3}") String a3){
demo = Demo.build(a1,a2,a3);
}

}
max58
2022-03-16 18:03:53 +08:00
@xjngbla Service 层 是有 @Swevice 这个注解的
max58
2022-03-16 18:05:08 +08:00
@zzfer 是有 @Service 注解的
max58
2022-03-16 18:05:43 +08:00
@BiChengfei 我去试一下
zzfer
2022-03-16 18:05:45 +08:00
如果你想在静态代码或非 spring 注解标注的类里使用。可以在 demo 里写好 a1 ,a2 ,a3 的 get 方法,通过这样获取
DemoConfig demoConfig = ApplicationContextHolder.getBean(DemoConfig .class);
String a1 = demoConfig .getA1();
ikas
2022-03-16 18:13:44 +08:00
bean 的生命周期基础,常用以下几种方案

1. 使用 @PostConstruct
2. 实现 InitializingBean 接口
3. 指定 initMethod 方法,如 @Bean(initMethod = "init")


如果想看详细,看 spring 文档 Receiving Lifecycle Callbacks 部分
paradoxs
2022-03-16 18:16:21 +08:00
如果是需要从配置中心获取值,要用 @PostConstruct
1194129822
2022-03-16 22:09:05 +08:00
知其然,知其所以然。楼主还停留在使用阶段,建议楼主去了解一下 spring bean 的生命周期,BeanPostProcessor ,InstantiationAwareBeanPostProcessor 。核心生成 bean 的逻辑在 AbstractAutowireCapableBeanFactory.doCreateBean ,大致流程 createBeanInstance->populateBean->initializeBean ,createBeanInstance 就是实例化,populateBean 就是填充属性,set 和字段注入(@Value ,@Autowired..),initializeBean 就是初始化( Aware, @PostConstruct ,InitializingBean..)。所以 initializeBean 阶段的回调都可以读取注入的值。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/840820

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX