spring学习总结005 --- IOC容器启动源码(事件机制)
2021-04-25 01:29
标签:mat tor stp str nta com hand sim interface 接着AbstractApplicationContext.refresh方法:initApplicationEventMulticaster,该方法用来初始化事件广播器,流程如下: 那么事件广播器有啥用呢?这要从spring提供的事件机制说起: 1、spring事件机制接口类 spring提供的事件机制是基于观察者模型或者订阅-发布模型的,spring提供了三个接口分别用于事件定义、事件发布、事件广播、事件监听:ApplicationEvent(抽象类更合理)、ApplicationEventPublisher、ApplicationEventMulticaster、ApplicationListener (1)ApplicationEvent ApplicationEvent应Java事件机制要求继承了EventObject,构造方法可以指定事件源 (2)ApplicationEventPublisher (3)ApplicationEventMulticaster (4)ApplicationListener 2、spring如何具有发送消息能力 refresh方法中有这样一个方法:prepareBeanFactory,用来为BeanFactory做一些定制化处理,其中有一行代码为BeanFactory添加了一个BeanPostProcessor ---- ApplicationContextAwareProcessor 该后置处理器在Bean初始化前对Aware接口类型的Bean做了一些特殊处理:将特定参数的bean传递给实现了Aware接口的bean;重点看ApplicationContextAwareProcessor中的invokeAwareInterfaces方法
ApplicationContext作为事件发布器??看ApplicationContext继承关系,发现ApplicationContext实现了ApplicationEventPublisher接口 3、spring事件广播能力 spring事件的发布依赖事件广播器,那么spring如何具有事件广播能力呢? spring在用户未配置名为applicationEventMulticaster的bean的情况下,创建了一个默认的事件广播器 ---- SimpleApplicationEventMulticaster,SimpleApplicationEventMulticaster通过multicastEvent方法来广播事件 那么事件发布器怎么利用事件广播器来广播事件呢?答案在AbstractApplicationContext的publishEvent方法。至此清楚了事件完整的发布机制 4、事件接收能力 ApplicationListener的实现类用来接收事件,spring框架怎么具备接收事件的能力呢?答案依旧在refresh方法调用的prepareBeanFactory方法中,该方法添加了一个BeanPostProcessor ---- ApplicationListenerDetector
在Bean初始化之后,会调用ApplicationListenerDetector的postProcessAfterInitialization方法
然后判断ApplicationContext中事件广播器是否为空,将事件监听器保存起来 5、实战示例 执行结果: spring学习总结005 --- IOC容器启动源码(事件机制) 标签:mat tor stp str nta com hand sim interface 原文地址:https://www.cnblogs.com/sniffs/p/13259860.htmlprotected void initApplicationEventMulticaster() {
// 获取BeanFactory, 默认是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果用户定义了name为applicationEventMulticaster的事件广播器, 直接将其作为容器的事件广播器
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 {
// 未自定义bean, 使用SimpleApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 将默认事件广播器存放到BeanFactory的beanDefinationMap中
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 multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
// 获取事件类型
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// 获取线程池
Executor executor = getTaskExecutor();
// 通过事件及类型获取对应的事件监听器
for (ApplicationListener> listener : getApplicationListeners(event, type)) {
// 异步或者同步方式广播事件
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener> listener, ApplicationEvent event) {
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处理
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
public class UserApplicationEvent extends ApplicationEvent {
public UserApplicationEvent(User user) {
super(user);
}
}
@Slf4j
@Component
public class UserApplicationEventPublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void saveUser(User user) {
log.info("start publish event.....");
applicationEventPublisher.publishEvent(new UserApplicationEvent(user));
}
}
@Slf4j
@Component
public class UserEventListener implements ApplicationListener
public class Test11 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean10.xml");
UserApplicationEventPublisher publisher = context.getBean(UserApplicationEventPublisher.class);
publisher.saveUser(User.builder()
.id(1)
.name("bale")
.info(Info.builder().age(28).build())
.build());
}
}
文章标题:spring学习总结005 --- IOC容器启动源码(事件机制)
文章链接:http://soscw.com/index.php/essay/79196.html