为什么使用@PostConstruct?

在托管bean中,@PostConstruct在常规Java对象构造函数之后调用。

为什么我要使用@PostConstruct来初始化bean,而不是常规构造函数本身?

321823 次浏览
  • 因为在调用构造函数时,bean还没有初始化——即没有注入依赖项。在@PostConstruct方法中,bean已完全初始化,您可以使用依赖项。

  • 因为这是保证该方法在bean生命周期中只被调用一次的契约。可能会发生(尽管不太可能)一个bean在其内部工作中被容器实例化多次,但它保证@PostConstruct只会被调用一次。

如果你的类在构造函数中执行所有的初始化,那么@PostConstruct确实是多余的。

然而,如果类的依赖项是使用setter方法注入的,那么类的构造函数就不能完全初始化对象,有时需要在调用所有setter方法之后执行一些初始化,因此出现了@PostConstruct的用例。

此外,每当涉及到某种代理或远程时,基于构造函数的初始化将不能按预期工作。

每当EJB被反序列化,或者每当为它创建一个新的代理时,就会调用ct……

主要问题是:

在构造函数中,依赖项的注入还没有发生*

*显然不包括构造函数注入


现实世界的例子:

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
}
}

< p > 重要的: @PostConstruct and @PreDestroy 已经完全删除在Java 11.

. 0

为了继续使用它们,你需要将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>

Gradle

// https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'