Spring中有个event事件,可以提供事件的定义、监听和发布事件操作,此次事件监听发布的实现采用的是观察者模式,这种一个地方发布了事件,需要另一个地方立刻监听感知到比较适合观察者模式,实现完毕,我们自定义实现的事件可以在spring生命周期里进行定义,监听发布。
在此种实现中,需要设计出事件定义,对事件的监听,以及对事件的发布,对事件的发布需要广播器进行处理等等,程序的入口,需要用到之前都一直在用的上下文刷新类AbstractApplicationContext的refresh(),用它初始化事件广播器,并发布一些刷新事件和关闭容器等事件,接下来咱们开始把
1.工程目录├─src │ ├─main │ │ ├─java │ │ │ └─com │ │ │ └─spring │ │ │ └─sourcecode │ │ │ │ SourcecodeApplication.java │ │ │ │ │ │ │ └─springframework │ │ │ │ BeanDefinition.java │ │ │ │ BeanFactory.java │ │ │ │ │ │ │ ├─beans │ │ │ │ │ BeansException.java │ │ │ │ │ PropertyValue.java │ │ │ │ │ PropertyValues.java │ │ │ │ │ │ │ │ │ └─factory │ │ │ │ │ Aware.java │ │ │ │ │ BeanClassLoaderAware.java │ │ │ │ │ BeanFactory.java │ │ │ │ │ BeanFactoryAware.java │ │ │ │ │ BeanNameAware.java │ │ │ │ │ ConfigurableListableBeanFactory.java │ │ │ │ │ DisposableBean.java │ │ │ │ │ FactoryBean.java │ │ │ │ │ HierarchicalBeanFactory.java │ │ │ │ │ InitializingBean.java │ │ │ │ │ ListableBeanFactory.java │ │ │ │ │ │ │ │ │ ├─config │ │ │ │ │ AutowireCapableBeanFactory.java │ │ │ │ │ BeanDefinition.java │ │ │ │ │ BeanFactoryPostProcessor.java │ │ │ │ │ BeanPostProcessor.java │ │ │ │ │ BeanReference.java │ │ │ │ │ ConfigurableBeanFactory.java │ │ │ │ │ SingletonBeanRegistry.java │ │ │ │ │ │ │ │ │ ├─support │ │ │ │ │ AbstractAutowireCapableBeanFactory.java │ │ │ │ │ AbstractBeanDefinitionReader.java │ │ │ │ │ AbstractBeanFactory.java │ │ │ │ │ BeanDefinitionReader.java │ │ │ │ │ BeanDefinitionRegistry.java │ │ │ │ │ CglibSubclassingInstantiationStrategy.java │ │ │ │ │ DefaultListableBeanFactory.java │ │ │ │ │ DefaultSingletonBeanRegistry.java │ │ │ │ │ DisposableBeanAdapter.java │ │ │ │ │ FactoryBeanRegistrySupport.java │ │ │ │ │ InstantiationStrategy.java │ │ │ │ │ SimpleInstantiationStrategy.java │ │ │ │ │ │ │ │ │ └─xml │ │ │ │ XmlBeanDefinitionReader.java │ │ │ │ │ │ │ ├─context │ │ │ │ │ ApplicationContext.java │ │ │ │ │ ApplicationContextAware.java │ │ │ │ │ ApplicationEvent.java │ │ │ │ │ ApplicationEventPublisher.java │ │ │ │ │ ApplicationListener.java │ │ │ │ │ ConfigurableApplicationContext.java │ │ │ │ │ │ │ │ │ ├─event │ │ │ │ │ AbstractApplicationEventMulticaster.java │ │ │ │ │ ApplicationContextEvent.java │ │ │ │ │ ApplicationEventMulticaster.java │ │ │ │ │ ContextClosedEvent.java │ │ │ │ │ ContextRefreshedEvent.java │ │ │ │ │ SimpleApplicationEventMulticaster.java │ │ │ │ │ │ │ │ │ └─supprot │ │ │ │ AbstractApplicationContext.java │ │ │ │ AbstractRefreshableApplicationContext.java │ │ │ │ AbstractXmlApplicationContext.java │ │ │ │ ApplicationContextAwareProcessor.java │ │ │ │ ClassPathXmlApplicationContext.java │ │ │ │ │ │ │ ├─core │ │ │ │ └─io │ │ │ │ ClassPathResource.java │ │ │ │ DefaultResourceLoader.java │ │ │ │ FileSystemResource.java │ │ │ │ Resource.java │ │ │ │ ResourceLoader.java │ │ │ │ UrlResource.java │ │ │ │ │ │ │ └─util │ │ │ ClassUtils.java │ │ │ │ │ └─resources │ │ application.properties │ │ spring.xml │ │ │ └─test │ └─java │ └─com │ └─spring │ └─sourcecode │ │ SourcecodeApplicationTests.java │ │ │ └─springframework │ │ ApiTest.java │ │ │ └─test │ └─event │ ContextClosedEventListener.java │ ContextRefreshedEventListener.java │ CustomEvent.java │ CustomEventListener.java │2.xml类图
1.ApplicationEvent
所有事件定义的父类,对于ContextRefreshedEvent来说就是刷新事件,对于ContextClosedEvent来说就是关闭事件的定义,就是用来对事件的定义
2.ApplicationListener事件监听器
ApplicationListener是个接口,当你想要实现刷新容器时进行监听可定义刷新监听器在进行实现ApplicationListener此接口,可用来自定义监听
3.ApplicationEventMulticaster
此接口是事件广播器,主要定义几个功能,用来注册事件监听器到容器里,从容器里删除监听器, 将给定的事件多播到对应发布出去
4.ApplicationEventPublisher
事件发布的定义接口,实现类里主要是用广播器发布出去
3.代码实现ApplicationEvent类,继承EventObject,主要是jdk自带的事件的父类
package com.spring.sourcecode.springframework.context;
import java.util.EventObject;
public abstract class ApplicationEvent extends EventObject {
public ApplicationEvent(Object source) {
// 调用父类的构造方法
super(source);
}
}
ApplicationContextEvent
package com.spring.sourcecode.springframework.context.event;
import com.spring.sourcecode.springframework.context.ApplicationContext;
import com.spring.sourcecode.springframework.context.ApplicationEvent;
public class ApplicationContextEvent extends ApplicationEvent {
public ApplicationContextEvent(Object source) {
super(source);
}
}
ContextClosedEvent
package com.spring.sourcecode.springframework.context.event;
public class ContextClosedEvent extends ApplicationContextEvent {
public ContextClosedEvent(Object source) {
super(source);
}
}
ContextRefreshedEvent
package com.spring.sourcecode.springframework.context.event;
public class ContextRefreshedEvent extends ApplicationContextEvent {
public ContextRefreshedEvent(Object source) {
super(source);
}
}
ApplicationEventMulticaster:定义事件广播器
package com.spring.sourcecode.springframework.context.event;
import com.spring.sourcecode.springframework.context.ApplicationEvent;
import com.spring.sourcecode.springframework.context.ApplicationListener;
// 事件广播器
public interface ApplicationEventMulticaster {
// 添加要通知所有事件的监听器
void addApplicationListener(ApplicationListener> listener);
// 从通知列表中删除监听器
void removeApplicationListener(ApplicationListener> listener);
// 将给定的应用程序事件多播到适当的监听器
void multicastEvent(ApplicationEvent applicationEvent);
}
AbstractApplicationEventMulticaster:定义抽象类实现ApplicationEventMulticaster类的部分实现,如addApplicationListener和removeApplicationListener。此类中还定义了getApplicationListeners(),主要是获取容器中所有的监听器是否符合你给定的监听事件,符合的进行返回,并调用对应的监听实现。
package com.spring.sourcecode.springframework.context.event;
import com.spring.sourcecode.springframework.beans.BeansException;
import com.spring.sourcecode.springframework.beans.factory.BeanFactory;
import com.spring.sourcecode.springframework.beans.factory.BeanFactoryAware;
import com.spring.sourcecode.springframework.context.ApplicationEvent;
import com.spring.sourcecode.springframework.context.ApplicationListener;
import org.springframework.util.ClassUtils;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Set;
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster {
private final Set> applicationListeners = new LinkedHashSet<>();
@Override
public void addApplicationListener(ApplicationListener> listener) {
applicationListeners.add((ApplicationListener) listener);
}
@Override
public void removeApplicationListener(ApplicationListener> listener) {
applicationListeners.remove(listener);
}
// 摘取符合广播事件中的监听处理器,具体过滤动作在supportsEvent中
// 1.将所有的和ApplicationListener类有关系的都存储到应用事件容器里
// 2.比如在bean处理时刷新到容器中完成时,则刷新事件并发布刷新事件
// 3.这时将传过来的刷新事件与之前存储容器事件进行对比
// 4.对比成功以后就存储到list以后返回
// 循环容器中存储的监听事件和你要发布的事件是否一致
protected Collection getApplicationListeners(ApplicationEvent event) {
LinkedList allListeners = new LinkedList();
for (ApplicationListener listener : applicationListeners) {
if (supportsEvent(listener, event)) allListeners.add(listener);
}
return allListeners;
}
protected boolean supportsEvent(ApplicationListener applicationListener, ApplicationEvent event) {
Class extends ApplicationListener> listenerClass = applicationListener.getClass();
// 按照 CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy 不同的实例化类型,需要判断后获取目标 class
Class> targetClass = ClassUtils.isCglibProxyClass(listenerClass) ? listenerClass.getSuperclass() : listenerClass;
Type genericInterface = targetClass.getGenericInterfaces()[0];
Type actualTypeArgument = ((ParameterizedType) genericInterface).getActualTypeArguments()[0];
String className = actualTypeArgument.getTypeName();
Class> eventClassName;
try {
eventClassName = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new BeansException("wrong event class name: " + className);
}
// 判定此 eventClassName 对象所表示的类或接口与指定的 event.getClass() 参数所表示的类或接口是否相同,或是否是其超类或超接口。
// isAssignableFrom是用来判断子类和父类的关系的,或者接口的实现类和接口的关系的,默认所有的类的终极父类都是Object。如果A.isAssignableFrom(B)结果是true,证明B可以转换成为A,也就是A可以由B转换而来。
return eventClassName.isAssignableFrom(event.getClass());
}
}
SimpleApplicationEventMulticaster:此类继承AbstractApplicationEventMulticaster广播器,当是匹配的监听器,实现发布广播。
package com.spring.sourcecode.springframework.context.event;
import com.spring.sourcecode.springframework.beans.factory.BeanFactory;
import com.spring.sourcecode.springframework.context.ApplicationEvent;
import com.spring.sourcecode.springframework.context.ApplicationListener;
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
// 调用实现的事件处理器
@Override
public void multicastEvent(final ApplicationEvent applicationEvent) {
for (final ApplicationListener listener : getApplicationListeners(applicationEvent)) {
listener.onApplicationEvent(applicationEvent);
}
}
}
ApplicationEventPublisher:事件发布定义
public interface ApplicationEventPublisher {
void publishEvent(ApplicationEvent event);
}
AbstractApplicationContext部分实现,只添加本节添加的东西,添加了初始化广播器
以及注册事件监听器,发布刷新容器,和关闭容器
@Override
public void refresh() {
// 6.
initApplicationEventMulticaster();
// 7.注册事件监听器
registerListeners();
// 8.提前实例化单例bean对象
// 通过beanDefinationMap里的实例对象将后续bean实例进行实例化,并处理后置修改的对象
beanFactory.preInstantiateSingletons();
// 9. 发布容器刷新完成事件
finishRefresh();
}
private void initApplicationEventMulticaster() {
//ConfigurableListableBeanFactory beanFactory = getBeanFactory();
applicationEventMulticaster = new SimpleApplicationEventMulticaster();
//beanFactory
}
// 将配置文件的关于监听的配置进行注册存储容器里
private void registerListeners() {
Collection applicationListeners = getBeansOfType(ApplicationListener.class).values();
for (ApplicationListener listener : applicationListeners) {
applicationEventMulticaster.addApplicationListener(listener);
}
}
private void finishRefresh() {
publishEvent(new ContextRefreshedEvent(this));
}
@Override
public void publishEvent(ApplicationEvent event) {
applicationEventMulticaster.multicastEvent(event);
}
@Override
public void close() {
// 发布容器关闭事件
publishEvent(new ContextClosedEvent(this));
getBeanFactory().destroySingletons();
}
4.测试准备
4.1 创建一个自定义事件和监听器
package com.spring.sourcecode.springframework.test.event;
import com.spring.sourcecode.springframework.context.event.ApplicationContextEvent;
public class CustomEvent extends ApplicationContextEvent {
private Long id;
private String message;
public CustomEvent(Object source, Long id, String message) {
super(source);
this.id = id;
this.message = message;
}
// 省略set/get
}
自定义事件监听器
package com.spring.sourcecode.springframework.test.event; import com.spring.sourcecode.springframework.context.ApplicationListener; import java.util.Date; public class CustomEventListener implements ApplicationListener{ @Override public void onApplicationEvent(CustomEvent event) { System.out.println("收到:" + event.getSource() + "消息;时间:" + new Date()); System.out.println("消息:" + event.getId() + ":" + event.getMessage()); } }
4.2 创建一个容器刷新事件监听器
package com.spring.sourcecode.springframework.test.event; import com.spring.sourcecode.springframework.context.ApplicationListener; import com.spring.sourcecode.springframework.context.event.ContextRefreshedEvent; public class ContextRefreshedEventListener implements ApplicationListener{ @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("刷新事件"); } }
4.3 创建一个事件关闭监听处理器
package com.spring.sourcecode.springframework.test.event; import com.spring.sourcecode.springframework.context.ApplicationListener; import com.spring.sourcecode.springframework.context.event.ContextRefreshedEvent; public class ContextRefreshedEventListener implements ApplicationListener{ @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("刷新事件"); } }
4.4 配置文件,将几个监听器配置进来
4.5 单元测试
public class ApiTest {
//
@Test
public void testFactoryBean() {
// 1.初始化BeanFactory
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
applicationContext.publishEvent(new CustomEvent(applicationContext, 1019129009086763L, "成功了!"));
applicationContext.registerShutdownHook();
}
}
5.测试结果



