事件监听器
准备发布事件逻辑
@Slf4j
@Component
static class MyService {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void doBusiness() {
log.warn("主线业务");
// 主线业务完成后 需要做一些支线业务
// log.warn("发送短信");
// log.warn("发送邮件");
applicationEventPublisher.publishEvent(new MyEvent("MyService#doBusiness"));
}
}
准备事件
static class MyEvent extends ApplicationEvent {
public MyEvent(Object source) {
super(source);
}
}
准备监听器-接口方式
@Slf4j
@Component
static class SmsApplicationListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
log.warn("发送短信");
}
}
@Slf4j
@Component
static class EmailApplicationListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
log.warn("发送邮件");
}
}
准备监听器-注解方式
@Slf4j
@Component
static class SmsService {
@EventListener
public void listener(MyEvent myEvent) {
log.warn("发送短信");
}
}
@Slf4j
@Component
static class EmailService {
@EventListener
public void listener(MyEvent myEvent) {
log.warn("发送邮件");
}
}
测试事件发布
@Configuration
public class TestEventListener {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestEventListener.class);
//initApplicationListener(applicationContext);
MyService myService = applicationContext.getBean(MyService.class);
myService.doBusiness();
applicationContext.close();
}
}
异步发送-绑定线程池
@Bean
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(3);
threadPoolTaskExecutor.setMaxPoolSize(10);
threadPoolTaskExecutor.setQueueCapacity(100);
return threadPoolTaskExecutor;
}
@Bean
public SimpleApplicationEventMulticaster applicationEventMulticaster(ThreadPoolTaskExecutor executor) {
// 配置异步的事件发送器
SimpleApplicationEventMulticaster applicationEventMulticaster = new SimpleApplicationEventMulticaster();
applicationEventMulticaster.setTaskExecutor(executor);
return applicationEventMulticaster;
}
模拟EventListener实现事件监听
/**
* 写一个自定义注解 来测试内部是怎么实现事件监听的
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyEventListener {
}
@Slf4j
@Component
static class SmsService {
@MyEventListener
public void listener(MyEvent myEvent) {
log.warn("发送短信");
}
}
@Slf4j
@Component
static class EmailService {
@MyEventListener
public void listener(MyEvent myEvent) {
log.warn("发送邮件");
}
}
编码方式实现并放入容器(不推荐)
private static void initApplicationListener(AnnotationConfigApplicationContext applicationContext) {
for (String beanName : applicationContext.getBeanDefinitionNames()) {
// 遍历所有bean下面的所有方法
Object bean = applicationContext.getBean(beanName);
for (Method method : bean.getClass().getMethods()) {
// 判断是否是MyEventListener
if (method.isAnnotationPresent(MyEventListener.class)) {
// 将当前方法包装层一个ApplicationListener bean
ApplicationListener applicationListener = event -> {
System.out.println("当前事件:" + event);
// 获取方法上的事件类型 判断类型一致才可以处理
Class<?> eventType = method.getParameterTypes()[0];
if (eventType.isAssignableFrom(event.getClass())) {
try {
method.invoke(bean, event);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
};
// 将包装好的监听器 放入容器
applicationContext.addApplicationListener(applicationListener);
}
}
}
}
利用SmartInitializingSingleton机制(推荐)
@Bean
public SmartInitializingSingleton myEventListeners(AnnotationConfigApplicationContext applicationContext) {
// SmartInitializingSingleton类是在所有单例对象完成后执行
return () -> {
for (String beanName : applicationContext.getBeanDefinitionNames()) {
Object bean = applicationContext.getBean(beanName);
for (Method method : bean.getClass().getMethods()) {
if (method.isAnnotationPresent(MyEventListener.class)) {
ApplicationListener applicationListener = event -> {
Class<?> eventType = method.getParameterTypes()[0];
if (eventType.isAssignableFrom(event.getClass())) {
try {
method.invoke(bean, event);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
};
applicationContext.addApplicationListener(applicationListener);
}
}
}
};
}
事件发布器
准备发布事件逻辑
@Slf4j
@Component
static class MyService {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void doBusiness() {
log.warn("主线业务");
applicationEventPublisher.publishEvent(new MyEvent("MyService#doBusiness"));
}
}
准备事件
static class MyEvent extends ApplicationEvent {
public MyEvent(Object source) {
super(source);
}
}
准备监听器
@Slf4j
@Component
static class SmsApplicationListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
log.warn("发送短信");
}
}
@Slf4j
@Component
static class EmailApplicationListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
log.warn("发送邮件");
}
}
抽象一个空实现所有方法的ApplicationEventMulticaster
static class MyAbstractEventMulticaster implements ApplicationEventMulticaster {
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
}
@Override
public void addApplicationListenerBean(String listenerBeanName) {
}
@Override
public void removeApplicationListener(ApplicationListener<?> listener) {
}
@Override
public void removeApplicationListenerBean(String listenerBeanName) {
}
@Override
public void removeApplicationListeners(Predicate<ApplicationListener<?>> predicate) {
}
@Override
public void removeApplicationListenerBeans(Predicate<String> predicate) {
}
@Override
public void removeAllListeners() {
}
@Override
public void multicastEvent(ApplicationEvent event) {
}
@Override
public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
}
}
准备线程池
@Bean
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(3);
threadPoolTaskExecutor.setMaxPoolSize(10);
threadPoolTaskExecutor.setQueueCapacity(100);
return threadPoolTaskExecutor;
}
自定义事件发布器
@Bean
public ApplicationEventMulticaster applicationEventMulticaster(AnnotationConfigApplicationContext applicationContext, ThreadPoolTaskExecutor executor) {
// 配置自定义的事件发送器
return new MyAbstractEventMulticaster() {
//private List<ApplicationListener> applicationListenerList = new ArrayList<>();
// GenericApplicationListener具备判断事件类型的能力
private List<GenericApplicationListener> applicationListenerList = new ArrayList<>();
// 收集事件监听器
@Override
public void addApplicationListenerBean(String listenerBeanName) {
ApplicationListener applicationListener = applicationContext.getBean(listenerBeanName, ApplicationListener.class);
ResolvableType interfaceEventType = ResolvableType.forClass(applicationListener.getClass()).getInterfaces()[0].getGeneric();
System.out.println("当前事件监听器为:" + applicationListener + ", 能够处理的事件类型为:" + interfaceEventType);
// 对事件进行包装 添加事件类型判断
GenericApplicationListener genericApplicationListener = new GenericApplicationListener() {
@Override
public boolean supportsEventType(ResolvableType eventType) {
// 是否支持某时间类型 eventType为当前的事件类型
return interfaceEventType.isAssignableFrom(eventType);
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
// 支持异步
executor.submit(() -> applicationListener.onApplicationEvent(event));
}
};
applicationListenerList.add(genericApplicationListener);
}
// 发布事件
@Override
public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
for (GenericApplicationListener applicationListener : applicationListenerList) {
if (applicationListener.supportsEventType(ResolvableType.forClass(event.getClass()))) {
applicationListener.onApplicationEvent(event);
}
}
}
};
}
测试
@Configuration
public class TestEventMulticaster {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestEventMulticaster.class);
MyService myService = applicationContext.getBean(MyService.class);
myService.doBusiness();
applicationContext.close();
}
}