Есть ли разница между использованием @PostConstruct
аннотации и объявлением того же метода, что и init-method
в конфигурации Spring XML?
Ответы:
Нет, практически я не думаю, что есть какая-то разница, но есть приоритеты в том, как они работают. @PostConstruct
, init-method
являются BeanPostProcessors.
@PostConstruct
- это аннотация JSR-250, а init-method
в Spring - метод инициализации.@PostConstruct
метод, он будет вызываться перед вызовом методов инициализации.afterPropertiesSet
, сначала @PostConstruct
вызывается, затем, afterPropertiesSet
а затем init-method
.Для получения дополнительной информации вы можете проверить справочную документацию Spring .
До спецификаций JSR 250 использование init-метода в xml было предпочтительным способом, поскольку он отделяет классы Java (beans) от любых классов / аннотаций, специфичных для Spring. Так что, если вы создаете библиотеку, которая не должна зависеть от компонентов инфраструктуры Spring тогда предпочтительным было использование init-метода. Во время создания метода u может указать метод, который должен быть вызван как метод инициализации.
Теперь, с введением спецификаций JSR 250 в Java EE и поддержкой Spring этих аннотаций, зависимость от фреймворка Spring в определенной степени уменьшилась.
Но я должен признать, что добавление этих вещей увеличивает читаемость кода, поэтому у обоих подходов есть свои плюсы и минусы.
Нет никакой реальной разницы. Все зависит от того, как вы предпочитаете настраивать свою систему, и это вопрос личного выбора. Лично я предпочитаю использовать @PostConstruct
аннотации для своего собственного кода (поскольку bean-компонент правильно настроен только после вызова метода), и я использую init-method
при создании экземпляров bean-компонентов из библиотек, не поддерживающих Spring (конечно, нельзя применять там аннотации!) но я могу полностью понять людей, которые так или иначе хотят все это делать.
@postconstruct не является частью весны. Это часть пакета javax. Оба одинаковые. с помощью init-метода нам нужно добавить в xml файл. Если вы используете @postconstruct, добавление в xml не требуется. Ознакомьтесь со статьей ниже.
Как вы можете видеть на приведенной ниже диаграмме обратного вызова жизненного цикла создания компонента .
Эти 3 шага выполняются в обратном вызове жизненного цикла создания компонента:
@PostConstruct
будет называться.InitializingBean
реализовано, то afterPropertiesSet()
будет называться.init-method
или @Bean(initmethod="..")
вызывает метод init.Эта диаграмма взята из Pro Spring 5: подробное руководство по Spring Framework и ее инструментам.
Там может быть разница между @PostConstruct
и init-method
потому , что @PostConstruct
обрабатывается в postProcessAfterInitialization
фазе инициализации боба ( AbstractAutowireCapableBeanFactory.initializeBean()
метод) с помощью CommonAnnotationBeanPostProcessor
, в то время как init
метод вызывается после завершения postProcessBeforeInitialization
фазы (и, по этому вопросу, до начала postProcessAfterInitialization
фазы).
РЕДАКТИРОВАТЬ : Итак, последовательность: 1) postProcessBeforeInitialization
фаза, 2) вызывается метод init
, 3) postProcessAfterInitialization
фаза, которая вызывает @PostConstruct
метод
(В качестве примечания, заявление из принятого ответа
@PostConstruct, метод инициализации - это BeanPostProcessors
не совсем правильно: @PostConstruct
обрабатывается a BeanPostProcessor
, init
метод - нет.)
Там будет разница , если некоторые (возможно под заказ) BeanPostProcessor
, который выполнен с ( Ordered.getOrder()
) , который будет выполняться после того, как CommonAnnotationBeanPostProcessor
, делает что - то серьезное в его postProcessBeforeInitialization
методе.
Нет никакой разницы с конфигурацией Spring по умолчанию, BeanPostProcessors
потому что все, BeanPostProcessors
которые настроены для выполнения после CommonAnnotationBeanPostProcessor
, ничего не делают в postProcessBeforeInitialization
методе.
В заключение, принятый ответ и подобные ему верны ... в 99% случаев, и этот пост - просто дань уважения концепции "дьявол кроется в деталях"
Полный код здесь: https://github.com/wkaczurba/so8519187 ( spring-boot )
Использование аннотаций:
@Slf4j
@Component
public class MyComponent implements InitializingBean {
@Value("${mycomponent.value:Magic}")
public String value;
public MyComponent() {
log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
}
@PostConstruct
public void postConstruct() {
log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
}
@Override // init-method; overrides InitializingBean.afterPropertiesSet()
public void afterPropertiesSet() {
log.info("MyComponent in afterPropertiesSet: [{}]", value); // (2) displays: Magic
}
@PreDestroy
public void preDestroy() {
log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
}
}
Получает нас:
Обновление org.springframework.context ...
MyComponent в конструкторе: [null]
MyComponent в postConstruct: [Magic]
MyComponent в afterPropertiesSet: [Magic]
...
Регистрация bean-компонентов для
отображения JMX при запуске Запущено DemoApplication через 0,561 секунды (JVM работает для 1.011)
Закрытие org.springframework.context .. . Отмена регистрации JMX-компонентов при завершении работы
...
MyComponent в preDestroy: [Magic]