Есть ли разница между использованием аннотации @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 и его инструментам