本文的核心内容:项目启动后(Spring Boot 项目加载完成、所有由Spring管理的Bean创建完成),我们需要初始化一些数据。这时,我们有两种方式可以解决这个问题。
一:CommandLineRunner和ApplicationRunner 接口
CommandLineRunner接口
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class CommandLineRunnerBean implements CommandLineRunner {
//注入相关Bean
@Override
public void run(String... args) {
//do something
}
}
ApplicationRunner 接口
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class ApplicationRunnerBean implements ApplicationRunner {
//注入相关Bean
@Override
public void run(ApplicationArguments arg0) throws Exception {
//do something
}
}
这两个接口中有一个run方法,我们只需要实现这个方法即可。这两个接口的不同之处在于:
ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中run方法的参数为String数组。
注意:多个接口实现类的调用顺序可以通过@Order(0)注解,数值越小优先执行。
二:事件监听
注入Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
SpringBoot 提供的五种事件
ApplicationStartedEvent springboot启动开始的时候执行的事件,在该事件中可以获取到SpringApplication对象,可做一些执行前的设置。
ApplicationEnvironmentPreparedEvent spring boot 对应Enviroment已经准备完毕,但此时上下文context还没有创建。在该监听中获取到ConfigurableEnvironment后可以对配置信息做操作。
ApplicationPreparedEvent spring boot上下文context创建完成,但此时spring中的bean是没有完全加载完成的。在获取完上下文后,可以将上下文传递出去做一些额外的操作。值得注意的是:在该监听器中是无法获取自定义bean并进行操作的。
ApplicationFailedEvent spring boot启动异常时执行事件,在异常发生时,最好是添加虚拟机对应的钩子进行资源的回收与释放,能友善的处理异常信息
ApplicationReadyEvent springboot 加载完成时候执行的事件
我们需要自定义监听器,实现我们需要的事件 调用初始化方法。
//这里我们监听的是Spring Boot 项目加载完成后的事件
@Component
public class MyApplicationReadyEventListener implements ApplicationListener<ApplicationReadyEvent>{
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
//事件触发时执行的业务逻辑
}
}
同样多个事件的执行顺序也可以通过@Order注解来控制。
提示:根据作者实测、接口与事件同时存在,接口的实现顺序先于事件,并且与@Order无关。
简言之,多个接口实现类的执行顺序可以通过@Order注解来控制,多个事件实现类的执行顺序@Order注解来控制。事件与接口的执行顺序无法通过@Order注解来控制,且接口优先级高于事件。
SpringBoot自定事件
定义事件【事件可以含有各种属性方法等等】
这些属性在事件发布的时候传递进来,提供给
/**
* 定义事件
*
*/public class MyApplicationEvent extends ApplicationEvent {
private String name;
//这里可以定义各种属性
//传入的Object 不能为Null, 随意一个数字,字符串都可以。
public MyApplicationEvent(Object source,String name) {
super(source);
this.name=name;
}
//get And set
}
定义监听器监听自定义事件【事件发生时,触发某种操作】
import org.springframework.context.ApplicationListener;
@Component
public class MyApplicationListener implements ApplicationListener<MyEvent> {
public void onApplicationEvent(MyEvent event) {
//通过 event可以获取到封装的属性
event.getName();
System.out.println("接收到事件:"+event.getClass());
}
}
发布事件
1)事件接口服务方式
public interface MyEventService{
public void publish(Object obj);
}
2)事件接口服务实现类
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class MyEventServiceImpl implements MyEventService{
/**
* 上下文对象
*/
@Resource
private ApplicationContext applicationContext;
@Override
public void publish(Object obj) {
//通过上下文对象发布监听
applicationContext.publishEvent(new MyApplicationEvent(" ","name"));
}
}
通过注入MyEventService,在需要触发事件的时候调用publish方法即可。