Вопрос-ответ

Why use @PostConstruct?

Зачем использовать @PostConstruct?

В управляемом компоненте @PostConstruct вызывается после обычного конструктора объектов Java.

Почему я должен использовать @PostConstruct для инициализации с помощью bean, а не самого обычного конструктора?

Переведено автоматически
Ответ 1

  • потому что при вызове конструктора компонент еще не инициализирован, т. Е. Никакие зависимости не вводятся. В методе @PostConstruct компонент полностью инициализирован, и вы можете использовать зависимости.


  • потому что это контракт, который гарантирует, что этот метод будет вызван только один раз в жизненном цикле компонента. Может случиться (хотя и маловероятно), что экземпляр компонента создается контейнером несколько раз при его внутренней работе, но это гарантирует, что @PostConstruct будет вызван только один раз.


Ответ 2

Вы всегда должны отдавать предпочтение внедрению конструктора, но с учетом сказанного, если по какой-либо причине вам приходится использовать внедрение поля, в этом случае основная проблема заключается в том, что:


в конструкторе внедрение зависимостей еще не произошло



Пример

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>

Gradle

// https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
Ответ 3

Если ваш класс выполняет всю свою инициализацию в конструкторе, то @PostConstruct действительно избыточен.

Однако, если в ваш класс внедрены зависимости с использованием методов setter , то конструктор класса не может полностью инициализировать объект, и иногда некоторую инициализацию необходимо выполнить после вызова всех методов setter, отсюда и вариант использования @PostConstruct.

Ответ 4

Также инициализация на основе конструктора не будет работать должным образом всякий раз, когда задействовано какое-либо проксирование или удаленное взаимодействие.

Ct будет вызываться всякий раз, когда EJB десериализуется, и всякий раз, когда для него создается новый прокси...

java jakarta-ee