Spring事件监听源码分析
我们接着分析refresh()方法中的事件监听的源码部分。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
//标签解析看过了
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//BeanDefinitionRegistry和BeanFactoryPostProcessor接口看过了
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//BeanPostProcessor接口看过了
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
//来看事件监听源码
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
//来看事件监听源码
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//如果自己在beanFactory中注册了多播器,用自己的
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//默认用SimpleApplicationEventMulticaster类型的多播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//这个方法看一看,这里注册的bean,是没有对应的beanDefinition的,要注意。
//还有destorySingleton的方法可以移除单例bean
//我们可以通过这两个方法随意增删单例bean
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
//不能注册同名的bean
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
//看这里
addSingleton(beanName, singletonObject);
}
}
protected void addSingleton(String beanName, Object singletonObject) {
//singletonObjects在这里放入了beanName,和bean的映射
//singletonObjects这个就是从spring中获取单例bean的缓存集合
//移除这两个singletonFactories,earlySingletonObjects集合中的数据
//详细等到讲到实例化和循环依赖我们再来深究
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
protected void registerListeners() {
// Register statically specified listeners first.
//获取到applicationContext中applicationListeners
//是一个Set<ApplicationListener<?>>集合
//可以通过applicationContext的addApplicationListener方法添加监听器
//注意调用时序,在refresh方法执行完以后在通过此种方法添加的,是没用的,该方法已经执行完了。
//多播器中就没有这个监听器了,就没法广播给它了
for (ApplicationListener<?> listener : getApplicationListeners()) {
//向多播器内部类ListenerRetriever的applicationListeners添加监听者
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 收集实现了ApplicationListener接口的被扫描的的beanName。
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
//向多播器内部类ListenerRetriever的applicationListenerBeans添加监听者
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
//这个是在registerListeners方法执行以前
//也就是多播器还没实例化或者
//监听者还未加入ApplicationListener或者ApplicationListenerBean集合中
//提前调用了applicationContext的publishEvent方法发布了的事件会暂存earlyApplicationEvents集合中
//直到这里我们再来发布这个集合中事件,然后该集合置为空
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
//事件发布
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
再来看事件发布的代码,也就是AbstractApplicationContext的publishEvent方法
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
//prepareRefresh方法会把earlyApplicationEvents = new LinkedHashSet<>();
//直到registerListeners方法调用之前,该集合都不为空
//也就是在多播器和监听器全都准备完毕之前,发布的事件都暂存在这个集合中
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
//registerListeners方法调用之后,earlyApplicationEvents = null
//再发布的事件直接走这里发布了
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
//子容器发布事件,父容器也会发布
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//获取多播器中的taskExecutor对象,如果不为空,异步执行监听者的代码
//可以使用多播器的setTaskExecutor方法设置Executor
Executor executor = getTaskExecutor();
//获取到全部的监听者,循环调用监听者的具体逻辑
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
private class ListenerRetriever {
//applicationListeners的值在ApplicationListenerDetector类中会添加监听者
//什么时候调用到ApplicationListenerDetector这个类的呢,等到讲到实例化bean的时候顺带提一下
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
public final Set<String> applicationListenerBeans = new LinkedHashSet<>();
private final boolean preFiltered;
public ListenerRetriever(boolean preFiltered) {
this.preFiltered = preFiltered;
}
public Collection<ApplicationListener<?>> getApplicationListeners() {
List<ApplicationListener<?>> allListeners = new ArrayList<>(
this.applicationListeners.size() + this.applicationListenerBeans.size());
//先添加applicationListeners的监听者
allListeners.addAll(this.applicationListeners);
if (!this.applicationListenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : this.applicationListenerBeans) {
try {
//beanFactory.getBean触发了我们监听者Bean的实例化
//如果是单例后续直接从singletonObjects集合中获取到对象
//beanFactory.getBean后面讲解实例化再详细说明
ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
//如果applicationListeners没有再添加,防止重复通知监听者
if (this.preFiltered || !allListeners.contains(listener)) {
//添加监听者
allListeners.add(listener);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Singleton listener instance (without backing bean definition) disappeared -
// probably in the middle of the destruction phase
}
}
}
if (!this.preFiltered || !this.applicationListenerBeans.isEmpty()) {
//对所有监听者排序
//AnnotationAwareOrderComparator继承OrderComparator实现了Comparator接口
//优先级 实现了PriorityOrdered接口的 > 实现Orderd接口的和@Order注解 > 啥都没有的
AnnotationAwareOrderComparator.sort(allListeners);
}
return allListeners;
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
//和设置Executor一样,也可以设置ErrorHandler用于处理监听者执行异常的情况
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
//看这里
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
//调用监听者的具体逻辑
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
到此,事件监听的相关代码就结束了。最后,举个简单的使用例子。
public class MyTest {
@Test
public void test1(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
//source可以传业务相关的对象
applicationContext.publishEvent(new MyEvent("hello event","source"));
}
}
public class MyEvent extends ApplicationEvent {
private String name;
public MyEvent(String name,Object source) {
super(source);
this.name = name;
}
}
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
}
}