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

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


当前回答

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

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

其他回答

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

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

因为在调用构造函数时,bean还没有初始化——即没有注入依赖项。在@PostConstruct方法中,bean已完全初始化,您可以使用依赖项。 因为这是保证该方法在bean生命周期中只被调用一次的契约。可能会发生(尽管不太可能)一个bean在其内部工作中被容器实例化多次,但它保证@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
    }
}

重要的是: @PostConstruct和@PreDestroy在Java 11中已经被完全移除。

要继续使用它们,您需要添加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'