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

我正在使用没有 Spring Boot 的 Spring Framework 4.3。据我了解 bean 生命周期:

  1. 加载 bean 定义

  2. 使用 beanFactoryPostProcessor 类处理 bean 定义

  3. 实例化和注入 bean(以正确的顺序循环)

  4. 使用豆类

  5. 让垃圾收集器销毁 bean

PropertyPlaceholderConfigurer是一个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 : null

url postconstruct : jdbc:mariadb://localhost:3306/client_project

Main : jdbc:mariadb://localhost:3306/client_project

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


不是吗?


我的代码有问题吗?还是我对bean生命周期的理解?


蓝山帝景
浏览 178回答 1
1回答

弑天下

当 spring 调用此构造函数时, url 属性为 null !如果必须在实例化 bean 之前读取 @Value 属性,则必须设置 url 并且与 null 不同。不是吗?这不是它的工作原理,如果ReadValueFromFilerequire的构造函数@Value那么只有 Spring 将保证在实例化ReadValueFromFile值url之前可用,否则 SpringReadValueFromFile使用默认构造函数进行实例化,然后通过调用属性的setter方法,url它将注入值。因此,在构造函数运行期间,您将看不到该值。您的代码没有任何问题。您需要了解 Spring 如何注入依赖项(或值):Constructor注入 - 表示依赖项/值必须在注入的依赖实例化期间存在Setter注入 - 表示依赖实例化期间不需要依赖项/值,但稍后将使用 setter 方法注入Field注入 - 表示依赖实例化期间不需要依赖项/值,但稍后将使用反射注入
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java