上一篇文章中,我们介绍了六种 SpringBoot 启动时运行代码的方法,并且详细介绍了其中两个可以获取和处理 spring 启动参数的方法:
本文我们继续来介绍剩下的四种方式。
在 org.springframework.boot.context.event 包中,定义了 SpringBoot 的启动事件类:
有了上述启动的六个关键时刻触发的事件,我们就可以编写事件响应程序来实现自定义处理了。
可以看到,相较于上一篇文章中介绍的 ApplicationRunner 与 CommandLineRunner 接口,监听和响应启动事件让我们对项目的 启动有了更细粒度的控制。
除了上一篇文章中已经提到的 ApplicationRunner 与 CommandLineRunner 接口,上面还提到了 ApplicationContext、ApplicationContextInitializers 接口等,这些关键概念我们后续会有文章专门介绍,敬请期待下文。
通过向注解 @EventListener 传入我们想要监听的事件类,就可以实现对这一事件的响应,例如:
@Component
public class RunAfterStartup{
@EventListener(ApplicationReadyEvent.class)
public void runAfterStartup() {
System.out.println("Yaaah, I am running........");
}
显然,我们不能像上一篇文章中那样轻松地获取启动参数了。
启动 SpringBoot,我们看到上述代码打印出了:
Yaaah, I am running........
也许你觉得编写事件响应太麻烦,那么,添加 @Postconstruct 注解的方式可能就是你想要的解决办法,这也是最常用的一种方法了。
只要在方法上加上这个 @Postconstruct 注解,这个方法就会在类创建完成后被立即调用。
@Component
public class PostContructImpl {
public PostContructImpl() {
System.out.println("PostContructImpl Constructor called");
}
@PostConstruct
public void runAfterObjectCreated() {
System.out.println("PostContruct method called");
}
}
执行上述代码,打印出了:
PostContructImpl Constructor calledpostContruct method called
这种方法本质上和添加 @Postconstruct 注解是一样的。都会在这个类完成创建和初始化工作后调用。
我们只要实现 InitializingBean 的 afterPropertiesSet 方法即可。
例如:
@Component
public class InitializingBeanImpl implements InitializingBean {
public InitializingBeanImpl() {
System.out.println("InitializingBeanImpl Constructor called");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBeanImpl afterPropertiesSet method called");
}
}
Spring 的 Bean 拥有一个属性 initMethod 可以让我们指定 bean 创建时的初始化方法,借助这个属性,我们就可以在其中添加我们想要的启动代码了。
需要注意的是,这个 initMethod 必须是没有参数和返回值。但这个方法可以使 static 的甚至是 private 的。
例如:
public class BeanInitMethodImpl {
public void runAfterObjectCreated() {
System.out.println("yooooooooo......... someone called me");
}
}
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean(initMethod="runAfterObjectCreated")
public BeanInitMethodImpl getFunnyBean() {
return new BeanInitMethodImpl();
}
}
打印出了:
yooooooooo......... someone called me
上述的这些方法都是可以同时添加到你的项目中,那么,这些方法一旦同时添加,到底他们之间执行的先后顺序如何呢?
他们是按照下面的顺序来执行的:
至于 ApplicationRunner 与 CommandLineRunner 的实现类,我们可以通过 @Order 注解决定他们之间的优先级。
https://stacktraceguru.com/springboot/run-method-on-startup#application-runner