Spring атрибут @PostConstruct vs. init-method

Есть ли разница между использованием аннотации @PostConstruct и объявлением того же метода, что и init-method в конфигурации Spring XML?

Ответ 1

Нет, практически я не думаю, что есть какая-то разница, но есть приоритеты в том, как они работают. @PostConstruct, init-method являются процессорами BeanPostProcessors.

  1. @PostConstruct - это аннотация JSR-250, а init-method - это способ Spring с использованием метода инициализации.
  2. Если у вас есть метод @PostConstruct, он будет вызван первым до вызова методов инициализации.
  3. Если ваш компонент реализует 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, не требуется. Ознакомьтесь с приведенной ниже статьей.

http://answersz.com/spring-postconstruct-and-predestroy/

Ответ 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

Как вы можете видеть на диаграмме обратного вызова жизненного цикла создания бина.

Bean Creation Life-Cycle Callback

Этот 3 шаг происходит в обратном вызове жизненного цикла создания бина:

  1. Упоминается, что будет вызван @PostConstruct.
  2. Если реализован InitializingBean, будет вызван afterPropertiesSet().
  3. Если определение бина содержит init-method или @Bean(initmethod=".."), то он вызывает метод init.

Эта диаграмма взята из Pro Spring 5: подробное руководство по Spring Framework и его инструментам