Есть ли разница между использованием аннотации @PostConstruct и объявлением того же метода, что и init-method в конфигурации Spring XML?
Spring атрибут @PostConstruct vs. init-method
Ответ 1
Нет, практически я не думаю, что есть какая-то разница, но есть приоритеты в том, как они работают. @PostConstruct, init-method являются процессорами BeanPostProcessors.
@PostConstruct- это аннотация JSR-250, аinit-method- это способ Spring с использованием метода инициализации.- Если у вас есть метод
@PostConstruct, он будет вызван первым до вызова методов инициализации. - Если ваш компонент реализует InitializingBean и переопределяет
afterPropertiesSet, сначала вызывается@PostConstruct, затемafterPropertiesSet, а затемinit-method.
Для получения дополнительной информации вы можете проверить справочную документацию Spring reference documentation.
До спецификаций JSR 250 предпочтительным способом было использование init-метода в xml, так как он отделяет java-классы (bean-компоненты) от любых классов/аннотаций, специфичных для Spring. Так что, если вы создаете библиотеку, которая не должна зависеть от bean-компонентов инфраструктуры Spring тогда использование init-метода было предпочтительным. Во время создания метода вы можете указать метод, который нужно вызвать как метод инициализации.
Теперь, с появлением спецификаций JSR 250 в Java EE и поддержкой Spring этих аннотаций, зависимость от среды Spring в некоторой степени уменьшена.
Но я должен признать, что добавление этих вещей повышает читабельность кода. Так что есть плюсы и минусы обоих подходов.
Ответ 2
Нет никакой реальной разницы. Это зависит от того, как вы предпочитаете настраивать свою систему, и это вопрос личного выбора. Сам я предпочитаю использовать аннотации @PostConstruct для моего собственного кода (поскольку bean только правильно настроен после вызова метода), и я использую init-method при создании экземпляров beans из не-w760 > -aware библиотек (я не могу использовать аннотации там, конечно!), но я могу полностью понять людей, желающих сделать все это так или иначе.
Ответ 3
@postconstruct не является частью spring. Это часть пакета javax. Оба они одинаковы. используя init-метод, нам нужно добавить в xml файл. Если вы используете добавление @postconstruct в xml, не требуется. Ознакомьтесь с приведенной ниже статьей.
Ответ 4
Полный код здесь: 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 в afterPropertiesSet: [Magic]
...
Регистрация bean-компонентов для JMX при запуске
Запуск DemoApplication через 0,561 секунды (JVM работает в течение 1,011)
Закрытие org.springframework.context... Отмена регистрации компонентов JMX при завершении работы
...
МойКомпонент в преДестрой: [Магия]
Ответ 5
Может быть разница между @PostConstruct и init-method потому что @PostConstruct обрабатывается в фазе postProcessAfterInitialization инициализации компонента AbstractAutowireCapableBeanFactory.initializeBean() метод AbstractAutowireCapableBeanFactory.initializeBean()) с помощью CommonAnnotationBeanPostProcessor, в то время как init-method postProcessBeforeInitialization после завершения и завершения для метода postProcessBeforeInitialization этот вопрос, до начала фазы postProcessAfterInitialization).
(Поэтому утверждение из принятого ответа
@PostConstruct, init-метод - это BeanPostProcessors
не совсем правильно: @PostConstruct обрабатывается BeanPostProcessor, init-method - нет.)
Будет разница, если какой-то (потенциально настраиваемый) BeanPostProcessor, который настроен (Ordered.getOrder()) для выполнения после CommonAnnotationBeanPostProcessor, делает что-то серьезное в своем методе postProcessBeforeInitialization.
Нет никакой разницы с конфигурацией по умолчанию Spring BeanPostProcessors потому что все BeanPostProcessors которые настроены для выполнения после CommonAnnotationBeanPostProcessor, ничего не делают в методе postProcessBeforeInitialization.
В заключение, принятый ответ и тому подобное являются правильными... в 99% случаев, и этот пост является просто данью концепции "дьявол кроется в деталях"
Ответ 6
Как вы можете видеть на диаграмме обратного вызова жизненного цикла создания бина.
Этот 3 шаг происходит в обратном вызове жизненного цикла создания бина:
- Упоминается, что будет вызван
@PostConstruct. - Если реализован
InitializingBean, будет вызванafterPropertiesSet(). - Если определение бина содержит
init-methodили@Bean(initmethod=".."), то он вызывает метод init.
Эта диаграмма взята из Pro Spring 5: подробное руководство по Spring Framework и его инструментам
