SpringBoot的默认启动事件
public class MyApplicationStartingEventListener implements ApplicationListener<ApplicationStartingEvent> {
@Override
public void onApplicationEvent(ApplicationStartingEvent event) {
System.out.println("ApplicationStartingEvent事件发布:" + event.getTimestamp());
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication app =new SpringApplication(Application.class);
app.addListeners(new MyApplicationStartingEventListener());//加入自定义的监听类
app.run(args);
}
}
自定义事件发布和监听:
为实现 ApplicationEvent事件的发布,开发者需要借助于 ApplicationContext,它提供了 publishEvent方法。Spring 的事件需要遵循如下流程:
(1) 自定义事件, 继承 ApplicaltionEvent。
(2) 定义事件监听器,实现ApplicationListener。
(3) 使用容器发布事件。
自定义源事件
源事件需要继承 ApplicationEvent
/**
* @Descript:源事件父类;定义规范;不同的源事件继承该类 重写 fire方法即可
*/
public abstract class AbstractEvent extends ApplicationEvent {
protected Object object;
protected ApplicationContext context;
public AbstractEvent(ApplicationContext context,Object object) {
super(context);
this.object=object;
this.context=context;
}
//同一触发的方法
public abstract void fire();
}
/**
* @Descript:源事件
*/
public class DemoEvent extends AbstractEvent {
public AutoGradingEvent(ApplicationContext context, String msg){
super(context,msg);
}
@Override
public void fire() {
String msg = (String )object;
System.out.println("事件执行主方法"+msg);
}
}
事件监听器:
实现事件监听有三种方式:
1、实现 ApplicationListener接口
/**
* 事件监听器
* 实现 ApplicationListener接口, 并指定监听的事件类型
*/
@Component
public class DemoListener implements ApplicationListener<AbstractEvent > {
/**
* @param event
* 使用 onApplicationEvent方法对消息进行接受处理
*/
public void onApplicationEvent(AbstractEvent event) {
String msg = event.fire();
System.out.println("执行自定义事件方法");
}
}
2、使用@EventListener(推荐使用这种)
/**
* @Descript: 监听
*/
@Component
public class DemoListener{
@EventListener
public void onApplicationEvent(AbstractEvent event) {
if (event instanceof AbstractEvent) event.fire();
}
}
3、实现 SmartApplicationListener接口
@Component
public class EventListener implements SmartApplicationListener {
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return true;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
AbstractEvent event= (AbstractEvent) applicationEvent;
event.fire();
}
}
事件发布:
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;//注入 AppllcationContext用来发布事件
/**
* @param msg
* 使用 AppllicationContext的 publishEvent方法来发布
*/
public void publish(String msg){
applicationContext.publishEvent(new DemoEvent(applicationContext,msg));
}
}
异步监听:
默认情况下,监听事件都是同步执行的。在需要异步处理时,可以在方法上加上@Async进行异步化操作。此时,可以定义一个线程池,同时开启异步功能,加入@EnableAsync
1、自定义异步处理线程池:
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
* @Descript: 异步处理事件 配置线程池
*/
@Configuration
@EnableAsync
public class ListenerAsyncConfiguration implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
//使用Spring内置线程池任务对象
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
//设置线程池参数
taskExecutor.setCorePoolSize(5);//最少维护数量
taskExecutor.setMaxPoolSize(100);//最大线程数量
taskExecutor.setQueueCapacity(300);//队列大小
/**
* rejection-policy:当pool已经达到max size的时候,如何处理新任务
* CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
*/
taskExecutor.setRejectedExecutionHandler(
new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
2、添加异步注解:
只需要在原来的事件监听方法上加上注解@Async即可
/**
* @Descript: 监听
*/
@Component
public class DemoListener{
@EventListener
@Async
public void onApplicationEvent(AbstractEvent event) {
if (event instanceof AbstractEvent) event.fire();
}
}