最近看到有说 Spring Event和SpringBoot Event两种 Event
仔细看才知道,他们将SpringApplication中新增的SpringApplicationRunListener
视为是SpringBoot Event的处理类,而以往实现ApplicationListener
的称为Spring Event
这么分有些道理,毕竟 SpringApplicationRunListener
是SpringBoot新引进的,且在SpringApplication
的run()
方法中进行调用,并且初始化在onRefresh()
之前。那我姑且接受这一分类方式
具体原理不做说明,可以参考SpringBoot中的事件机制
自定义Spring Event 示例
自定义 Spring Event 可以自定义 Event
、publisher
和listener
public class ISpringEvent extends ApplicationEvent {
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public ISpringEvent(Object source) {
super(source);
}
}
@Component
public class ISpringEventPublisher {
@Autowired
private ApplicationEventPublisher publisher;
public void publish(){
ISpringEvent springEvent = new ISpringEvent(this);
publisher.publishEvent(springEvent);
}
}
// 实现接口方式
@Component
public class ISpringEventListener implements ApplicationListener<ISpringEvent> {
@Override
public void onApplicationEvent(ISpringEvent event) {
System.out.println("This is event listener");
}
}
// 注解实现方式
@Component
public class ISpringAnnotationEventListener {
@EventListener(classes = ISpringEvent.class)
public void onEvent(){
System.out.println("This is Annotation Event listener");
}
}
运行结果:
This is Annotation Event listener
This is event listener
自定义SpringBoot Event 示例
其实这篇随笔最主要是为了记录这里的一个坑
自定义SpringBoot Event的时候,由于SpringApplication#getRunListener
方法里指定了其构造函数的参数为
SpringApplication
和String[]
,因此一直要自定义一个构造函数
private SpringApplicationRunListeners getRunListeners(String[] args) {
// 构造函数的参数数组
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
因此必须实现一个(SpringApplication application, String[] args)
的构造函数
否则会保错Caused by: java.lang.NoSuchMethodException: com.wesley.xxx.springboot.ISpringBootListener.<init>(org.springframework.boot.SpringApplication, [Ljava.lang.String;)
则对应的代码为
public class ISpringBootListener implements SpringApplicationRunListener , Ordered {
@Override
public void starting() {
System.out.println("context starting");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
System.out.println("environment settled");
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
}
@Override
public void started(ConfigurableApplicationContext context) {
}
@Override
public void running(ConfigurableApplicationContext context) {
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
}
@Override
public int getOrder() {
return 0;
}
public ISpringBootListener(SpringApplication application, String[] args) {
}
}
并在配置文件META-INF/spring.factories
中加上
org.springframework.boot.SpringApplicationRunListener=\
com.wesley.myannoation.event.springboot.ISpringBootListener
此时的Event的语句输出在启动日志里