java jframe пример - Зачем использовать @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 .
Чтобы продолжать использовать их, вам нужно добавить 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>
Gradle
// https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
В управляемом компоненте @PostConstruct
вызывается после обычного конструктора объектов Java.
Почему я должен использовать @PostConstruct
для инициализации bean-компонентом вместо обычного конструктора?
Рассмотрим следующий сценарий:
public class Car {
@Inject
private Engine engine;
public Car() {
engine.initialize();
}
...
}
Поскольку автомобиль должен быть создан до ввода в эксплуатацию, двигатель точки впрыска остается нулевым во время выполнения конструктора, в результате чего возникает исключение NullPointerException.
Эта проблема может быть решена либо JSR-330 Injection Injection для встраивания конструктора Java, либо JSR 250 Common Annotations для аннотации метода Java @PostConstruct.
@PostConstruct
JSR-250 определяет общий набор аннотаций, который был включен в Java SE 6.
Аннотации PostConstruct используются для метода, который необходимо выполнить после того, как выполняется инъекция зависимостей для выполнения любой инициализации. Этот метод ДОЛЖЕН быть вызван до того, как класс будет запущен в эксплуатацию. Эта аннотация ДОЛЖНА поддерживаться на всех классах, поддерживающих инъекцию зависимостей.
JSR-250 Chap. 2.5 javax.annotation.PostConstruct
Аннотирование @PostConstruct позволяет определить методы, которые будут выполняться после того, как экземпляр был создан, и все инъекции были выполнены.
public class Car {
@Inject
private Engine engine;
@PostConstruct
public void postConstruct() {
engine.initialize();
}
...
}
Вместо выполнения инициализации в конструкторе код перемещается в метод, аннотированный с помощью @PostConstruct.
Обработка постконструктивных методов - это простой вопрос о поиске всех методов, аннотированных с помощью @PostConstruct, и их последующего вызова.
private void processPostConstruct(Class type, T targetInstance) {
Method[] declaredMethods = type.getDeclaredMethods();
Arrays.stream(declaredMethods)
.filter(method -> method.getAnnotation(PostConstruct.class) != null)
.forEach(postConstructMethod -> {
try {
postConstructMethod.setAccessible(true);
postConstructMethod.invoke(targetInstance, new Object[]{});
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
});
}
Обработка постконструктивных методов должна выполняться после завершения инкапсуляции и впрыска.