我正在将控制器转换为较新的注释版本。在旧版本中,我曾经使用以下方法在 springmvc-servlet.xml 中指定 init 方法:
<beans>
<bean id="myBean" class="..." init-method="init"/>
</beans>
如何使用注释版本指定 init 方法?
您可以使用
@PostConstruct
public void init() {
// ...
}
Spring中有几种方法可以拦截初始化过程。如果您必须初始化所有 bean 并自动装配/注入它们,我知道至少有两种方法可以确保这一点。我只有第二个testet,但我相信两者的工作方式相同。
如果你使用@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 的实现。
我有两个相互依赖的类(@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 在一切准备就绪并配置后最后运行。
@PostConstruct、实现 InitializingBean、指定 init-method 他们有调用命令。所以你不能用它们来替换init-method。你可以试试这个:
@Bean(initMethod = "init")
public MyBean mybean() {
return new MyBean();
}
class MyBean {
public void init() {
System.out.println("MyBean init");
}
}
在你的类中,你可以声明一个名为 init() 的方法。
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
}
}