在托管的Bean中,@PostConstruct
是在常规Java对象构造函数之后调用的。
为什么我要使用@PostConstruct
来初始化我的bean,而不是直接使用常规构造函数呢?
在托管的Bean中,@PostConstruct
是在常规Java对象构造函数之后调用的。
为什么我要使用@PostConstruct
来初始化我的bean,而不是直接使用常规构造函数呢?
因为在调用构造函数时,bean 尚未初始化,即没有注入任何依赖项。在 @PostConstruct
方法中,bean 已经完全初始化,您可以使用依赖项。
因为这是保证该方法仅在 bean 生命周期中被调用一次的协议。虽然容器在内部工作中可能多次实例化一个 bean,但它保证只会调用一次 @PostConstruct
。
在构造函数中,依赖项的注入尚未发生
例子
public class Foo {
@Inject
Logger LOG;
@PostConstruct
public void fooInit(){
LOG.info("This will be printed; LOG has already been injected");
}
public Foo() {
LOG.info("This will NOT be printed, LOG is still null");
// NullPointerException will be thrown here
}
}
重要
@PostConstruct
和@PreDestroy
在Java 11中已完全移除(https://jaxenter.com/jdk-11-java-ee-modules-140674.html)。
如果要继续使用它们,您需要将javax.annotation-api JAR添加到您的依赖项中。
Maven
<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
// https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
@PostConstruct
。 - Rookie007如果你的类在构造函数中完成了所有初始化操作,那么@PostConstruct
确实是多余的。
但是,如果你的类使用setter方法注入其依赖关系,那么类的构造函数就不能完全初始化对象,有时需要在调用所有setter方法后执行某些初始化操作,因此需要使用@PostConstruct
。
当涉及到代理或远程调用时,基于构造函数的初始化也无法按预期工作。
每当EJB被反序列化时,都会调用ct,并且每当为其创建新代理时也会调用ct...
final
。鉴于这种模式,为什么J2EE要添加@PostConstruct
呢?他们一定又看到了其他用例吧? - mjaggard@PostConstruct
并不用于适当地注入依赖项,以确保它们是final
等;它被用作一个实用程序的注释,该实用程序应该被 IoC 容器构造多次调用 一次。虽然我不知道这在容器中如何发生,但显然它是可能发生的(请参见已接受的答案)。 - Jason