java中监听器代码剖析,Spring 源码解析

一. 测试用例

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:

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">

测试类:

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 earlyEventsToProcess = this.earlyApplicationEvents;

this.earlyApplicationEvents = null;

if (earlyEventsToProcess != null) {

for (ApplicationEvent earlyEvent : earlyEventsToProcess) {

getApplicationEventMulticaster().multicastEvent(earlyEvent);

}

}

}

来源:[]()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值