我正在使用没有Spring Boot的Spring Framework 4.3。 据我对bean生命周期的了解:
PropertyPlaceholderConfigurer
是BeanFactoryPostProcessor
。
因此必须在实例化bean之前读取@Value
属性。 (第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!
如果必须在实例化bean之前读取@Value
属性,那么必须设置url并使其不同于null。
不是吗?
我的代码有问题吗?或根据我对bean生命周期的了解?
答案 0 :(得分:4)
spring调用此构造方法时,url属性为null!如果必须在实例化bean之前读取@Value属性,则必须设置url且该URL不同于null。是吗?
这不是它的工作方式,如果ReadValueFromFile
的构造函数需要@Value
,那么只有Spring会保证在实例化ReadValueFromFile
之前url
值可用,否则Spring实例化ReadValueFromFile
使用默认构造函数,然后调用setter
属性的url
方法,它将注入该值。
因此,在构造函数运行期间,您将看不到该值。
您的代码没有错。
您需要了解Spring如何注入依赖项(或值):
Constructor
注入-意味着在注入的依赖实例化期间必须存在依赖关系/值Setter
注入-表示在依赖实例化过程中不需要依赖项/值,但稍后将使用setter方法注入Field
注入-表示在依赖实例化过程中不需要依赖项/值,但是稍后将使用反射注入