364

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

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

4

4 回答 4

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

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

于 2010-08-04T14:40:04.820 回答
128

主要问题是:

在构造函数中,依赖项的注入尚未发生*

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


真实世界的例子:

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 添加到您的依赖项中。

马文

<!-- 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'
于 2014-11-27T14:33:21.410 回答
68

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

但是,如果您的类使用 setter 方法注入了其依赖项,则该类的构造函数无法完全初始化对象,并且有时需要在调用所有 setter 方法后执行一些初始化,因此@PostConstruct.

于 2010-08-04T14:46:59.380 回答
1

每当涉及某种代理或远程处理时,基于构造函数的初始化也不会按预期工作。

每当 EJB 被反序列化,并且每当为它创建新代理时,都会调用 ct...

于 2011-10-16T15:34:30.003 回答