Spring自定义事件及事件源码分析

一、使用

Spring事件体系包括三个组件:事件、发布器、监听器。事件是主体,发布器负责发布事件,监听器负责处理事件。Spring事件使用的是监听者模式,他的优点在于低耦合、侵入性相对较小。

Spring自定义事件及事件源码分析_第1张图片

下面介绍下Spring事件如何使用。

1、定义事件

自定义事件需要继承ApplicationEvent。Spring里面也内置了很多事件也都是基于继承ApplicationEvent类

Spring自定义事件及事件源码分析_第2张图片

下面我们自己定义一个事件,该事件主要处理订单对象Order

/**
 * 定义订单事件
 * @author jiangleilei
 * @date 2023/10/10 09:34
 */
public class OrderEvent extends ApplicationEvent {
    private Order order;
    public OrderEvent(Object source, Order order) {
        super(source);
        this.order = order;
    }
}

2、定义监听器

事件监听器需要实现ApplicationListener接口,一个事件可以有多个监听者,当时间发布时,所有该事件的监听者都可以收到监听通知。

/**
 * 事件监听器,专监听OrderEvent事件
 * @author jiangleilei
 * @date 2023/10/10 09:36
 */
@Component  //监听器需要交给Spring管理,至于为什么下文会有提到
public class OrderEventListener implements ApplicationListener<OrderEvent> {

    //event = 事件对象
    @Override
    public void onApplicationEvent(OrderEvent event) {
        //通过事件对象,我们可以拿到事件里面的任何属性,如果需要更多信息,我们也可以在事件里面定义更多属性
        Order order = event.getOrder();
        System.out.println("收到监听事件1");
    }
}

3、发布事件

//将ApplicationContext注入到类里面去
@Autowired
private ApplicationContext applicationContext;

public void xxx{
	//创建事件,第一个参数传什么都不重要,但就是不能为null
	OrderEvent order = new OrderEvent(this, new Order());
	//发布事件
	applicationContext.publishEvent(order);
}

二、源码分析

1、添加后置处理

在spring启动刷新的时候,会有一个准备工作也就是prepareBeanFactory方法,里面会添加BeanPostProcessor,也就是ApplicationListenerDetector后置处理器,所有的后置处理器基本上都是在实例化某些Bean的时候,对Bean做一些特殊处理,必须这个是否给这个Bean生成代理等等。。

prepareBeanFactory(beanFactory);

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	....
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
	....
}

ApplicationListenerDetector属于BeanPostProcessor类型,所以任何bean的实例化,包括spring自带的bean,都要通过doGetBean创建bean实例,那么就会走到后置处理的回调方法中

ApplicationListenerDetector:主要作用:

  1. 在任何Bean初始化完成之后:如果Bean是单例的并且bean是ApplicationListener类型,则加入到this.applicationListeners中,applicationListeners会在广播通知的时候,会遍历监听者发送通知
  2. 在任何Bean销毁之前: 如果Bean是ApplicationListener类型,则会从ApplicationEventMulticaster(事件广播器)中删除。

比如上面自定义的监听者OrderEventListener就会被加到applicationListeners里面去

2、执行后置处理器

下面是部分源码:

class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
   
   //初始化之前
   @Override
   public Object postProcessAfterInitialization(Object bean, String beanName) {
      if (bean instanceof ApplicationListener) {//判断bean是否ApplicationListener类型
         Boolean flag = this.singletonNames.get(beanName);//判断是否是单利
         if (Boolean.TRUE.equals(flag)) {
            this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
         }
         else if (Boolean.FALSE.equals(flag)) {
            if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
         		.....
            }
            this.singletonNames.remove(beanName);
         }
      }
      return bean;
   }
    //销毁之前
   @Override
   public void postProcessBeforeDestruction(Object bean, String beanName) {
      if (bean instanceof ApplicationListener) {
         try {
            ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
            multicaster.removeApplicationListener((ApplicationListener<?>) bean);
            multicaster.removeApplicationListenerBean(beanName);
         }
         catch (IllegalStateException ex) {
         }
      }
   }
}
//添加到applicationListeners事件监听器集合里面去
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

@Override
public void addApplicationListener(ApplicationListener<?> listener) {
	...
	this.applicationListeners.add(listener);
}

3、发布事件

public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {

	//1、线程池处理
	@Override
	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		Executor executor = getTaskExecutor(); //如果有指定线程池,那就通过指定线程池里面的线程来调用监听器,处理事件。
		for (ApplicationListener<?> listener : getApplicationListeners(event, type)) { //getApplicationListeners拿到指定类型事件的监听器
			
			//否则通过当前线程调用监听器。最终都是调用下面的invokeListener方法。
			if (executor != null) {
				executor.execute(() -> invokeListener(listener, event));
			}else {
				invokeListener(listener, event);
			}
		}
	}

	//2、异常处理
	protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
		ErrorHandler errorHandler = getErrorHandler(); //判断是否有处理发布异常的Handler
		if (errorHandler != null) {
			try {
				doInvokeListener(listener, event);
			}
			catch (Throwable err) {
				errorHandler.handleError(err);
			}
		}
		else {
			doInvokeListener(listener, event);
		}
	}

	//3、通过我们自定义的监听器,触发重写的onApplicationEvent方法
	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
		listener.onApplicationEvent(event);
	}	
}

你可能感兴趣的:(Spring整理后,spring,事件监听器,自定义,源码)