您的位置:首页 > 编程语言 > Java开发

Spring 源码解析 ---- 事件监听

2016-11-23 10:08 375 查看
一. 测试用例

package main.java.com.wenniuwuren.spring.event.listener;

import org.springframework.context.ApplicationEvent;

/**
* 定义监听事件
* Created by hzzhuyibin on 2016/11/22.
*/
public class TestEvent extends ApplicationEvent {

public String msg;

/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public TestEvent(Object source) {
super(source);
}

public TestEvent(Object source, String msg) {
super(source);
this.msg = msg;
}

public void print() {
System.out.println(msg);
}

}
package main.java.com.wenniuwuren.spring.event.listener;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

/**
* 定义监听器
* Created by hzzhuyibin on 2016/11/22.
*/
public class TestListener implements ApplicationListener{
@Override
public void onApplicationEvent(ApplicationEvent event) {

if (event instanceof TestEvent) {
TestEvent testEvent = (TestEvent)event;
testEvent.print();
}
}
}


listenerTest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="testListener" class="main.java.com.wenniuwuren.spring.event.listener.TestListener"/>

</beans>

测试类:
package main.java.com.wenniuwuren.spring.event.listener;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
*
* Created by Yibin_Zhu on 2016/11/21.
*/
public class Test{

public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("main/resources/listenerTest.xml");
// 不仅仅可以指定 beanName,也可以有构造函数或者工厂方法的方法参数

TestEvent testEvent = new TestEvent("hello", "wenniuwuren");

context.publishEvent(testEvent);

}
}

二. 源码解析
debug 到 AbstractApplicationContext 类的 initApplicationEventMulticaster() 方法

广播器我们又经常成为事件
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 用户自定义事件广播器
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else { // 默认事件广播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}

我们关注的是 SimpleApplicationEventMulticaster 事件类的具体实现,继续 debug 进去,看到此类继承自 AbstractApplicationEventMulticaster, 而 AbstractApplicationEventMulticaster 中有许多 add**Listener、delete**Listener 之类的方法,可以知道这是典型的观察者模式的应用。

继续看如下方法:事件在这里广播,遍历所有监听器,通知监听器
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}

@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
invokeListener(listener, event);
}
}
}

protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
listener.onApplicationEvent(event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
listener.onApplicationEvent(event);
}
}


这个方法 debug 结束,回到 AbstractApplicationContext 类,debug 进 registerListeners() 方法:注册监听器

protected void registerListeners() {
// 硬编码的方式注册监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}

// 配置文件注册监听器
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}

// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: