为了账号安全,请及时绑定邮箱和手机立即绑定

Spring Bean 生命周期 - 构造函数中的 @value 属性为空

Spring Bean 生命周期 - 构造函数中的 @value 属性为空

蓝山帝景 2022-07-20 10:10:02
我正在使用没有 Spring Boot 的 Spring Framework 4.3。据我了解 bean 生命周期:加载 bean 定义使用 beanFactoryPostProcessor 类处理 bean 定义实例化和注入 bean(以正确的顺序循环)使用豆类让垃圾收集器销毁 beanPropertyPlaceholderConfigurer是一个BeanFactoryPostProcessor。因此@Value必须在实例化 bean 之前读取属性。(第2步)。这是我的代码,主类:public static void main(String[] args) {    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);    ReadValueFromFile dc = ctx.getBean(ReadValueFromFile.class);    System.out.println("Main : " + dc.getUrl());}ReadValueFromFile.java@Component@PropertySource("classpath:db/db.properties")public class ReadValueFromFile {    @Value("${url}")    private String url;    public ReadValueFromFile() {        System.out.println("url constructor : " +  url);    }    @PostConstruct    void init() {        System.out.println("url postconstruct : " +  url);    }    @PreDestroy    void dest() {        System.out.println("url @PreDestroy : " +  url);    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }}配置类:@Configuration@ComponentScan(basePackages={"tn.esprit.beans"})public class AppConfig {     //it works well without declaring this bean.//   @Bean//   public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {//      return new PropertySourcesPlaceholderConfigurer();//   }}最后是我在 src/main/resources/db 下的属性文件:url=jdbc:mariadb://localhost:3306/client_project当我运行主类时,我得到这个输出:url constructor : nullurl postconstruct : jdbc:mariadb://localhost:3306/client_projectMain : jdbc:mariadb://localhost:3306/client_project当 spring 调用此构造函数时, url 属性为 null !如果@Value必须在实例化 bean 之前读取属性,则必须设置 url 并且与 null 不同。不是吗?我的代码有问题吗?还是我对bean生命周期的理解?
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

当 spring 调用此构造函数时, url 属性为 null !如果必须在实例化 bean 之前读取 @Value 属性,则必须设置 url 并且与 null 不同。不是吗?

这不是它的工作原理,如果ReadValueFromFilerequire的构造函数@Value那么只有 Spring 将保证在实例化ReadValueFromFileurl之前可用,否则 SpringReadValueFromFile使用默认构造函数进行实例化,然后通过调用属性的setter方法,url它将注入值。

因此,在构造函数运行期间,您将看不到该值。

您的代码没有任何问题。

您需要了解 Spring 如何注入依赖项(或值):

  1. Constructor注入 - 表示依赖项/值必须在注入的依赖实例化期间存在

  2. Setter注入 - 表示依赖实例化期间不需要依赖项/值,但稍后将使用 setter 方法注入

  3. Field注入 - 表示依赖实例化期间不需要依赖项/值,但稍后将使用反射注入


查看完整回答
反对 回复 2022-07-20
  • 1 回答
  • 0 关注
  • 173 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信