`

Spring 使用的设计模式(二) Observer(观察者)

阅读更多

spring在容器中使用了观察者模式:

  spring事件:ApplicationEvent, 事件,该抽象类继承了EventObject,jdk建议所有的事件都应该继承自EventObject

  spring事件监听器:ApplicationLisener

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(E event);

}

   该接口继承了EventListener接口,jdk建议所有的事件监听器都应该继承EventListener

 

  spring事件发布:ApplicationEventPublisher , ApplicationContext继承了该接口,在ApplicationContext的抽象类AbstractApplicationContext中做了实现

public interface ApplicationEventPublisher {

	/**
	 * Notify all listeners registered with this application of an application
	 * event. Events may be framework events (such as RequestHandledEvent)
	 * or application-specific events.
	 * @param event the event to publish
	 * @see org.springframework.web.context.support.RequestHandledEvent
	 */
	void publishEvent(ApplicationEvent event);

}

  

  AbstractApplicationContext类中publishEvent方法实现:

 

	public void publishEvent(ApplicationEvent event) {
		Assert.notNull(event, "Event must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Publishing event in " + getDisplayName() + ": " + event);
		}
                //事件广播委托给ApplicationEventMulticaster来进行
		getApplicationEventMulticaster().multicastEvent(event);
		if (this.parent != null) {
			this.parent.publishEvent(event);
		}
	}

   由上代码可知,AbstractApplicationContext类并没有具体的做事件广播,而是委托给ApplicationEventMulticaster来进行,ApplicationEventMulticaster的multicastEvent()方法实现如下:

	public void multicastEvent(final ApplicationEvent event) {
		for (final ApplicationListener listener : getApplicationListeners(event)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {
				executor.execute(new Runnable() {
					public void run() {
						listener.onApplicationEvent(event);
					}
				});
			}
			else {
				listener.onApplicationEvent(event);
			}
		}
	}

 获得listener集合,遍历listener触发事件Executor接口有多个实现类,可以支持同步或异步广播事件

 

现在大家可能有个疑问,spring容器是怎么根据事件去找到事件对应的事件监听器呢?

在spring容器初始化的时候,

 

	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);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// 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) {
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}
		}
	}
 initApplicationEventMulticaster()方法代码为:

 

 

	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
                //先查找BeanFactory配置文件中是否有ApplicationEventMulticaster
		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 {//如果beanFactory中没有,则创建一个SimpleApplicationEventMulticaster
			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 + "]");
			}
		}
	}
 spring先从beanFactory中获取ApplicationEventMulticaster,如果没有自定义,则创建一个SimpleApplicationEventMulticaster

 

 

ApplicationEventMulticaster包含以下属性:defaultRetriever即为注册表,注册监听事件的相关消息,retrieverCache用来做defaultRetriever的缓存

 

public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanFactoryAware {

	private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);

	private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
			new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);

	private BeanFactory beanFactory;
 ListenerRetriever的数据结构如下:applicationListeners用来存放监听事件, applicationListenerBeans为存放监听事件的类名称
	private class ListenerRetriever {

		public final Set<ApplicationListener> applicationListeners;

		public final Set<String> applicationListenerBeans;

		private final boolean preFiltered;
 

 

初始化注册表以后,则把事件注册到注册表中,registerListeners():

 

	protected void registerListeners() {
		// Register statically specified listeners first.
                //获取所有的listener, 把事件的bean放到ApplicationEventMulticaster中的
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
                //把事件的名称放到ApplicationListenerBean里去
		for (String lisName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(lisName);
		}
	}
 spring根据反射机制,通过方法getBeansOfType()获取所有继承了ApplicationListener接口的监听器,然后把监听器全放到注册表里,所以我们可以在spring配置文件中配置自定义的监听器,在spring初始化的时候会把监听器自动注册到注册表中。

 在applicationContext发布事件的时候,

 

	public void publishEvent(ApplicationEvent event) {
		Assert.notNull(event, "Event must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Publishing event in " + getDisplayName() + ": " + event);
		}
                //调用ApplicationEventMulticaster的multicastEvent()方法
		getApplicationEventMulticaster().multicastEvent(event);
		if (this.parent != null) {
			this.parent.publishEvent(event);
		}
	}
 ApplicationEventMulticaster的方法multicastEvent()为:

 

 

	public void multicastEvent(final ApplicationEvent event) {
                //获取对应的listener,触发事件
		for (final ApplicationListener listener : getApplicationListeners(event)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {
				executor.execute(new Runnable() {
					public void run() {
						listener.onApplicationEvent(event);
					}
				});
			}
			else {
				listener.onApplicationEvent(event);
			}
		}
	}
 getApplicationListeners()方法的实现为:

 

 

	protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) {
                //获取事件类型
		Class<? extends ApplicationEvent> eventType = event.getClass();
                //获取事件源类型
		Class sourceType = event.getSource().getClass();
		ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
                //从缓存里查找ListenerRetriever                  
		ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
                //如果不为空,则返回对应的listener
		if (retriever != null) {
			return retriever.getApplicationListeners();
		}
		else {//如果缓存里不存在,则去获得
                        //先创建要返回对象
			retriever = new ListenerRetriever(true);
			LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
			Set<ApplicationListener> listeners;
			Set<String> listenerBeans;
                        //获取注册表里所有的listener
			synchronized (this.defaultRetriever) {
				listeners = new LinkedHashSet<ApplicationListener>(this.defaultRetriever.applicationListeners);
				listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
			}
                        //根据事件类型,事件源类型,获取所需要的监听事件
			for (ApplicationListener listener : listeners) {
				if (supportsEvent(listener, eventType, sourceType)) {
					retriever.applicationListeners.add(listener);
					allListeners.add(listener);
				}
			}
			if (!listenerBeans.isEmpty()) {
				BeanFactory beanFactory = getBeanFactory();
				for (String listenerBeanName : listenerBeans) {
					ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
					if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
						retriever.applicationListenerBeans.add(listenerBeanName);
						allListeners.add(listener);
					}
				}
			}
			OrderComparator.sort(allListeners);
			this.retrieverCache.put(cacheKey, retriever);
			return allListeners;
		}
	}
 配合上面的注解,即可理解,根据事件类型找到对应的监听器,那么如何根据事件类型找到对应的监听器呢?

 上面方法中的supportsEvent(listener, eventType, sourceType)方法实现了根据事件类型查找对应的监听器,代码具体实现为:

	protected boolean supportsEvent(
			ApplicationListener listener, Class<? extends ApplicationEvent> eventType, Class sourceType) {

		SmartApplicationListener smartListener = (listener instanceof SmartApplicationListener ?
				(SmartApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
		return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
	}

 如上可知:上面方法的返回结果跟方法smartListener.supportsEventType(eventType)和smartListener.supportsSourceType(sourceType)有关

smartListener.supportsEventType(eventType)方法实现为:

	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
		Class<?> typeArg = GenericTypeResolver.resolveTypeArgument(this.delegate.getClass(), ApplicationListener.class);
		if (typeArg == null || typeArg.equals(ApplicationEvent.class)) {
			Class<?> targetClass = AopUtils.getTargetClass(this.delegate);
			if (targetClass != this.delegate.getClass()) {
				typeArg = GenericTypeResolver.resolveTypeArgument(targetClass, ApplicationListener.class);
			}
		}
		return (typeArg == null || typeArg.isAssignableFrom(eventType));
	}

 该方法主要的逻辑就是根据事件类型判断是否和监听器参数泛型的类型是否一致,可还记得监听器ApplicationListener的代码?

 

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(E event);

}

 在定义自己的监听器要明确指定参数泛型,表明该监听器支持的事件,如果不指明具体的泛型,则没有监听器监听事件

smartListener.supportsSourceType(sourceType)方法的实现为:

    public boolean supportsSourceType(Class<?> sourceType) {
        return true;
    }

 

默认返回true

 

以上是spring的事件体系,

 

我们可以使用spring的事件广播体系,自定义自己的事件:

自定义事件,继承ApplicationEvent:

public class DIYEvent extends ApplicationEvent {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1540593978873145453L;

	public DIYEvent(String content) {
		super(content);
	}

}

 

自定义listener,继承ApplicationListener

public class Test1Listener implements ApplicationListener<DIYEvent> {

	public void onApplicationEvent(DIYEvent event) {
		System.out.println(event.getSource());
	}

}

 在spring的配置文件中配置此listener

<!-- 自定义监听器 -->
   <bean id="test1Listener" class="test.obsever.listener.Test1Listener"></bean>

 

测试触发事件:

public class TestDemo {
	
	private ApplicationContext context;
	
	private MessageSource resources;
	
	@Before
	public void before() {
		context = new FileSystemXmlApplicationContext("WebRoot/WEB-INF/spring/spring.xml");
	}

	public static void main(String[] args) {
		
	}
	
	@Test
	public void testA() {
		context.publishEvent(new DIYEvent("test data!"));
	}
	
	@After
	public void after() {
		
	}
}

 获取ApplicationContext,发布事件

 

调试结果:test data!

分享到:
评论

相关推荐

    设计模式--观察者模式java例子

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    设计模式 观察者 发布/订阅 Observer

    当一个对象的改变同时会影响其他对象的行为的时候,可以使用此设计模式。 l 主题对象 :一个需要被关注的主题对象,这个主题对象改变会影响其他对象的行为 l 订阅对象:当主题对象发生改变,订阅对象需要相应处理...

    设计模式学习之Observer(观察者模式)

    **观察者模式(Observer Pattern)**是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式在分布式系统、事件...

    观察者模式(Observer)

    观察者模式(Observer)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态变化时通知多个“观察”该对象的其他对象。这个模式在软件工程中广泛应用于事件驱动编程,例如用户界面组件的交互或者系统状态的...

    设计模式之观察着模式Observer

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动的编程...

    第四章:Spring AOP API 设计模式1

    13. **观察者模式(Observer)**:Spring AOP并没有直接实现观察者模式,但在Spring事件模型中,`ApplicationEventPublisher`和`ApplicationListener`接口体现了观察者模式,允许对象注册监听并响应特定事件。...

    Observer(观察者模式)学习源码

    Observer模式,也称为订阅或发布-订阅模式,是软件设计模式中的行为模式之一。它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式广泛应用于事件...

    设计模式之观察者模式.pdf

    观察者模式(Observer Pattern)是一种常用的行为设计模式,它允许对象之间建立一种一对多的关系,即多个对象可以监听一个对象的状态变化,当这个对象的状态发生改变时,所有相关的对象(观察者)都会收到通知并自动...

    23钟设计模式之观察者模式

    观察者模式是软件设计模式中的一种行为模式,它允许一个对象(称为观察者)在其他对象(称为主题)的状态发生变化时自动收到通知并做出相应的行为。这种模式在系统设计中非常常见,尤其在事件驱动和实时数据更新的...

    跟着 Guava、Spring 学习如何设计观察者模式.doc

    观察者模式是一种行为设计模式,它允许对象在状态改变时通知其他对象,这些对象被称为观察者。这种模式常用于创建事件驱动的系统,使得多个组件能够对特定事件作出响应。在Java中,Guava和Spring框架都提供了实现...

    Java EE设计模式:Spring企业级开发最佳实践

    在 Spring 中,观察者模式广泛应用于事件驱动编程中,例如,在 Spring MVC 中,使用观察者模式来处理请求和响应。 4.MVC Pattern:模型视图控制器模式,分离应用程序的关注点,实现高内聚、低耦合的设计。 在 ...

    24种设计模式以及混合设计模式

    1. 在Web开发中,Spring框架就广泛应用了设计模式,如工厂模式用于创建Bean,单例模式保证每个Bean只有一个实例,观察者模式用于事件驱动编程,策略模式用于实现AOP(面向切面编程)。 2. 在游戏开发中,状态模式常...

    观察者模式Demo

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动编程,使得多...

    java设计模式之观察者模式

    其中,观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。观察者模式在事件驱动系统中尤其常见,如...

    Observer设计模式

    在Java中,除了标准库提供的Observable和Observer之外,还可以使用第三方库如Guava的EventBus或Spring框架的ApplicationEventPublisher接口来实现观察者模式,这些库提供了更高级的功能和更好的扩展性。 总之,...

    Spring 5 Design Patterns.pdf

    - **观察者模式(Observer)**:定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 - **适配器模式(Adapter)**:将一个类的接口转换成客户希望的另一个...

    观察者模式学习

    观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在软件工程中,这种模式被广泛应用于事件驱动编程和异步通信中。在这个主题...

    Java观察者模式案例

    观察者模式是软件设计模式中的一种行为模式,它在对象之间定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式广泛应用于事件处理、发布订阅系统、消息...

    观察者模式图和代码实现

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式常用于事件驱动编程,使得系统...

    观察者模式

    9. **扩展**:除了Java内置的`Observer`和`Observable`,开发者还可以使用第三方库如Guava的`EventBus`,或者Spring框架的`ApplicationEvent`和`ApplicationListener`,这些都提供了更高级的观察者模式实现。...

Global site tag (gtag.js) - Google Analytics