Ответ 1
Вы можете использовать
@PostConstruct
public void init() {
// ...
}
Я конвертирую контроллер в новую версию аннотации. В старой версии я использовал метод init в springmvc-servlet.xml, используя:
<beans>
<bean id="myBean" class="..." init-method="init"/>
</beans>
Как я могу указать метод init с использованием версии аннотации?
Вы можете использовать
@PostConstruct
public void init() {
// ...
}
В качестве альтернативы вы можете реализовать свой класс InitializingBean
для предоставления функции обратного вызова (afterPropertiesSet()
), которую ApplicationContext будет вызывать, когда bean.
Существует несколько способов перехвата процесса инициализации spring. Если вам нужно инициализировать все бобы и использовать autowire/inject, есть, по крайней мере, два способа, о которых я знаю, это обеспечит это. У меня есть только второй тест, но я считаю, что оба они работают одинаково.
Если вы используете @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. Это дало мне некоторые головные боли, так как я не мог доверять @PostConstruct, так как автоустановка/инъекция установщиком еще не была выполнена. Заказ - это конструктор, @PostConstruct, затем автоуровневые сеттеры. Я решил это с помощью аннотации @EventListener, которая будет длиться последней и в то же самое время для всех боб. В этом примере также показана реализация InitializingBean.
У меня есть два класса (@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 запускается последним после того, как все готово и настроено.
public class InitHelloWorld implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("BeforeInitialization : " + beanName);
return bean; // you can return any other object as well
}
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("AfterInitialization : " + beanName);
return bean; // you can return any other object as well
}
}