Существует несколько способов перехватить процесс инициализации в Spring. Если вам нужно инициализировать все bean-компоненты и автоматически подключить / внедрить их, я знаю, что это как минимум два способа гарантируют это. У меня есть только второй тест, но я верю, что оба работают одинаково.
Если вы используете @Bean, вы можете ссылаться на initMethod, как это.
@Configuration
public class BeanConfiguration {
@Bean(initMethod="init")
public BeanA beanA() {
return new BeanA();
}
}
public class BeanA {
// method to be initialized after context is ready
public void init() {
}
}
Если вы используете @Component, вы можете аннотировать с помощью @EventListener следующим образом.
@Component
public class BeanB {
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
}
}
В моем случае у меня есть устаревшая система, в которой я сейчас использую IoC / DI, где Spring Boot является выбранной средой. Старая система привносит в таблицу много циклических зависимостей, и поэтому я должен часто использовать setter-dependency. Это вызвало у меня некоторые головные боли, так как я не мог доверять @PostConstruct, так как автоматическое подключение / инжекция с помощью setter еще не было сделано. Порядок конструктор, @PostConstruct, а затем автоматические установщики. Я решил это с помощью аннотации @EventListener, которая будет выполняться в последний раз и в одно и то же время для всех bean-компонентов. В примере показана реализация InitializingBean aswell.
У меня есть два класса (@Component) с зависимостью друг от друга. Классы выглядят одинаково для целей данного примера, отображая только один из них.
@Component
public class BeanA implements InitializingBean {
private BeanB beanB;
public BeanA() {
log.debug("Created...");
}
@PostConstruct
private void postConstruct() {
log.debug("@PostConstruct");
}
@Autowired
public void setBeanB(BeanB beanB) {
log.debug("@Autowired beanB");
this.beanB = beanB;
}
@Override
public void afterPropertiesSet() throws Exception {
log.debug("afterPropertiesSet()");
}
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
log.debug("@EventListener");
}
}
Это вывод журнала, показывающий порядок вызовов при запуске контейнера.
2018-11-30 18:29:30.504 DEBUG 3624 --- [ main] com.example.demo.BeanA : Created...
2018-11-30 18:29:30.509 DEBUG 3624 --- [ main] com.example.demo.BeanB : Created...
2018-11-30 18:29:30.517 DEBUG 3624 --- [ main] com.example.demo.BeanB : @Autowired beanA
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanB : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanB : afterPropertiesSet()
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : @Autowired beanB
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : afterPropertiesSet()
2018-11-30 18:29:30.607 DEBUG 3624 --- [ main] com.example.demo.BeanA : @EventListener
2018-11-30 18:29:30.607 DEBUG 3624 --- [ main] com.example.demo.BeanB : @EventListener
Как видите, @EventListener запускается последним после того, как все готово и настроено.