文章目录
16.容器事件
1. 概念
Spring的ApplicationContext能够发布事件并且允许注册相应的事件监听器,因此,它拥有一套完善的时间发布和监听机制。,5个基本概念:

-
事件(EventObject):发送的事件
-
事件监听器:监听事件,事件发生时,做出相应的处理
-
事件源:事件的产生者,任何一个EventObject必须拥有一个事件源
-
事件监听器注册表:组件或者框架的事件监听器不可能漂浮在空中,而必须有所存在,当事件产生时,会通知这些位于事件监听器注册表中的监听器
-
事件广播器:事件和事件监听器沟通的桥梁,负责把事件通知给事件监听器
事件体系,其实是观察者的一种具体实现方式,观察者模式,请参见
2. Spring事件类结构
1. 事件类 ApplicationEvent
2. 事件监听接口 ApplicationListener
3. 事件广播 ApplicationEventMulticaster
当事件发容器事件时,容器主控程序将调用时间广播器将事件通知给事件监听器注册表中的事件监听器.
3. 实现示例
通过模拟发送邮件的例子模拟事件的发布
-
事件:MailSendEvent
package com.desmond.springlearning.event; import org.springframework.context.ApplicationContext; import org.springframework.context.event.ApplicationContextEvent; import org.springframework.stereotype.Component; /** * @author presleyli * @date 2018/10/28 下午1:25 */ public class MailSenderEvent extends ApplicationContextEvent { private String to; public MailSenderEvent(ApplicationContext source, String to) { super(source); this.to = to; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } } -
事件监听器,当收到事件通知,负责具体业务逻辑处理
package com.desmond.springlearning.event; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * @author presleyli * @date 2018/10/28 下午1:26 */ @Component public class MailSenderListener implements ApplicationListener<MailSenderEvent> { public void onApplicationEvent(MailSenderEvent mailSenderEvent) { System.out.println("listener向" + mailSenderEvent.getTo() + "发送了一封邮件."); } } -
事件源
package com.desmond.springlearning.event; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * @author presleyli * @date 2018/10/28 下午1:28 */ @ComponentScan(basePackages = "com.desmond.springlearning.event") @Configuration public class MailSender { @Autowired private ApplicationContext applicationContext; public void sendMail(String to) { System.out.println("MailSender模拟发邮件..."); applicationContext.publishEvent(new MailSenderEvent(this.applicationContext, to)); } } -
测试类:
package com.desmond.springlearning.event; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /** * @author presleyli * @date 2018/10/28 下午1:31 */ public class Test { public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MailSender.class); MailSender mailSender = applicationContext.getBean(MailSender.class); mailSender.sendMail("desmond@desmond.com"); } } -
Output
MailSender模拟发邮件... listener向desmond@desmond.com发送了一封邮件. -
过程分析:
-
事件(EventObject):MailSendEvent
-
事件监听器:MailSenderListener
-
事件源:MailSender
-
事件监听器注册表:ApplicationEventMulticaster, Application根据反射机制,从BeanDefinitionRegistry中找出所有实现了ApplicationListener的Bean,并将他们注册至
ApplicationEventMulticaster. 其注册与广播方法为:/* * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.context.event; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.core.ResolvableType; /** * Interface to be implemented by objects that can manage a number of * {@link ApplicationListener} objects, and publish events to them. * * <p>An {@link org.springframework.context.ApplicationEventPublisher}, typically * a Spring {@link org.springframework.context.ApplicationContext}, can use an * ApplicationEventMulticaster as a delegate for actually publishing events. * * @author Rod Johnson * @author Juergen Hoeller * @author Stephane Nicoll */ public interface ApplicationEventMulticaster { /** * Add a listener to be notified of all events. * @param listener the listener to add */ void addApplicationListener(ApplicationListener<?> listener); /** * Add a listener bean to be notified of all events. * @param listenerBeanName the name of the listener bean to add */ void addApplicationListenerBean(String listenerBeanName); /** * Remove a listener from the notification list. * @param listener the listener to remove */ void removeApplicationListener(ApplicationListener<?> listener); /** * Remove a listener bean from the notification list. * @param listenerBeanName the name of the listener bean to add */ void removeApplicationListenerBean(String listenerBeanName); /** * Remove all listeners registered with this multicaster. * <p>After a remove call, the multicaster will perform no action * on event notification until new listeners are being registered. */ void removeAllListeners(); /** * Multicast the given application event to appropriate listeners. * <p>Consider using {@link #multicastEvent(ApplicationEvent, ResolvableType)} * if possible as it provides a better support for generics-based events. * @param event the event to multicast */ void multicastEvent(ApplicationEvent event); /** * Multicast the given application event to appropriate listeners. * <p>If the {@code eventType} is {@code null}, a default type is built * based on the {@code event} instance. * @param event the event to multicast * @param eventType the type of event (can be null) */ void multicastEvent(ApplicationEvent event, ResolvableType eventType); } -
事件广播器:ApplicationEventMulticaster.
-

658

被折叠的 条评论
为什么被折叠?



