Spring Application Event

项目结构

工程下载

https://github.com/xiaoheike/SpringApplicationEventExample.git

SportEvent

package nd.esp.com.event;

import org.springframework.context.ApplicationEvent;

public class SportEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L; public SportEvent(Object source) {
super(source);
}
}

SportEvent是所有体育运动的父类,继承Spring ApplicationEvent,必须实现带参数构造函数,如上述代码所示。带参数构造函数传入参数可用于携带其他的信息。具体在NBAEvent中可以看到作用。

NBAEvent

package nd.esp.com.event;

public class NBAEvent extends SportEvent {

    private static final long serialVersionUID = 1L;

    private String text;

    public NBAEvent(Object source) {
super(source);
} public NBAEvent(String source, String text) {
super(source);
this.text = text;
} public String news() {
return text;
} @Override
public String getSource() {
return String.class.cast(super.getSource());
}
}

NBAEvent主题,用于显示NBA相关信息,上述getSource()方法重写了Spring ApplicationEvent 的父类EventObject,可以用于获得构造函数传入的参数。

SoccerEvent

package nd.esp.com.event;

public class SoccerEvent extends SportEvent {

    private static final long serialVersionUID = 1L;

    private String text;

    public SoccerEvent(String source) {
super(source);
} public SoccerEvent(Object source, String text) {
super(source);
this.text = text;
} public String news() {
return text;
} @Override
public String getSource() {
return String.class.cast(super.getSource());
}
}

SoccerEvent主题,用于显示足球先关信息,和NBAEvent功能类似。

SportEventListener

SportEventListener1

package nd.esp.com.listener;

import nd.esp.com.event.NBAEvent;
import nd.esp.com.event.SoccerEvent;
import nd.esp.com.event.SportEvent; import org.springframework.context.ApplicationListener; public class SportEventListener implements ApplicationListener<SportEvent> { public void onApplicationEvent(SportEvent event) {
if (event instanceof NBAEvent) {
System.out.println("SportEventListener1:" + NBAEvent.class.cast(event).getSource());
}
if (event instanceof SoccerEvent) {
SoccerEvent soccerEvent = SoccerEvent.class.cast(event);
System.out.println("SportEventListener1:" + soccerEvent.getSource() + " " + soccerEvent.news());
}
}
}

SportEventListener2

package nd.esp.com.listener;

import nd.esp.com.event.NBAEvent;
import nd.esp.com.event.SoccerEvent;
import nd.esp.com.event.SportEvent; import org.springframework.context.ApplicationListener; public class SportEventListener2 implements ApplicationListener<SportEvent> { public void onApplicationEvent(SportEvent event) {
if (event instanceof NBAEvent) {
System.out.println("SportEventListener2:" + NBAEvent.class.cast(event).getSource());
}
if (event instanceof SoccerEvent) {
SoccerEvent soccerEvent = SoccerEvent.class.cast(event);
System.out.println("SportEventListener2:" + soccerEvent.getSource() + " " + soccerEvent.news());
}
}
}

SportEventListener是观察者,当有新事件到来会被调用。SportEvent的功能在这里得到体现,通过创建父类,可以同时监控一类相似的主题,比如NBA事件以及足球事件。这样可以少些监听者。可以有多个观察者监听相同的时间,这里是指SportEvent。

SportEventPublisher

package nd.esp.com.publisher;

import nd.esp.com.event.NBAEvent;
import nd.esp.com.event.SoccerEvent;
import nd.esp.com.event.SportEvent; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class SportEventPublisher implements ApplicationContextAware {
private ApplicationContext applicationEventPulisher = null; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationEventPulisher = applicationContext;
} public void publishEvent(SportEvent sportEvent) {
applicationEventPulisher.publishEvent(sportEvent);
} public static void main(String[] args) {
String[] xmlConfig = new String[] { "applicationContext.xml" };
// 使用ApplicationContext来初始化系统
ApplicationContext context = new ClassPathXmlApplicationContext(xmlConfig);
SportEventPublisher publisher = (SportEventPublisher) context.getBean("applicationContextAware");
publisher.publishEvent(new NBAEvent("NBA sport:骑士队获得总冠军"));
publisher.publishEvent(new SoccerEvent("Scorrer sport:标题:中国获得世界杯冠军", "中国击败世界各国,取得10连冠")); } }

SportEventPublisher当有新的时间时,由它发布,这个类继承Spring ApplicationContextAware,能够自动注入ApplicationContext对象。这个类实现了主题的通知功能。

appicationContext.xml(单线程)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="applicationContextAware" class="nd.esp.com.publisher.SportEventPublisher"></bean>
<bean id="applicationListener1" class="nd.esp.com.listener.SportEventListener1"></bean>
<bean id="applicationListener2" class="nd.esp.com.listener.SportEventListener2"></bean>
</beans>

这两个bean是必须的,id可以任意,spring针对SportEventPublisher肯定是有经过特殊处理的,要不然该类中的ApplicationEventPublisher无法注入对应类。

这样的配置默认是采用单线程,为了提高效率可以使用多线程。修改application.xml文件如下即可。

applicationContext.xml(多线程)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="applicationContextAware" class="nd.esp.com.publisher.SportEventPublisher"></bean>
<bean id="applicationListener1" class="nd.esp.com.listener.SportEventListener1"></bean>
<bean id="applicationListener2" class="nd.esp.com.listener.SportEventListener2"></bean> <bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="keepAliveSeconds" value="30000" />
<property name="maxPoolSize" value="1000" />
<property name="queueCapacity" value="200" />
</bean>
<bean id="applicationEventMulticaster"
class="org.springframework.context.event.SimpleApplicationEventMulticaster">
<property name="taskExecutor" ref="taskExecutor" />
</bean>
</beans>

idapplicationEventMulticaster不能够改变,猜测是spring需要根据这个id注入对象。

SimpleApplicationEventMulticaster

多线程或者单线程可以通过该类中的方法

@SuppressWarnings("unchecked")
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);
}
}
}

多线程产经下变量executor的值不为空,单线程则相反。

运行结果##

教程结束,感谢阅读。

欢迎转载,但请注明本文链接,谢谢。

2016.5.12 17:49

Spring Application Event Example的更多相关文章

  1. Spring 事件:Application Event

    Spring Application Event Spring 的事件(Application Event)为 Bean 与 Bean 之间的消息通信提供了支持.当一个 Bean 处理完一个任务之后, ...

  2. Spring Boot实战笔记(四)-- Spring常用配置(事件Application Event)

    一.事件(Application Event) Spring的事件为Bean和Bean之间的消息通信提供了支持.当一个Bean处理完一个任务之后,希望另一个Bean知道并能做相应的处理,这时我们就需要 ...

  3. spring boot: 一般注入说明(五) @Component, application event事件为Bean与Bean之间通信提供了支持

    spring的事件,为Bean与Bean之间通信提供了支持,当一个Bean处理完成之后,希望另一个Bean知道后做相应的事情,这时我们就让另外一个Bean监听当前Bean所发送的事件. spring的 ...

  4. 从命令模式的维度理解Spring 之Application Event

    Spring的事件(Application Event)为Bean与Bean之间的信息通讯提供了支持.当一个Bean处理完一个任务之后,希望另一Bean指定并能做相应的处理,这时我们就需要让另外一个B ...

  5. Spring Session event事件分析

    1. org.apache.catalina.session.StandardSession 这是servlet-api jar包中的一个类.是session接口的标准实现.当session创建的时候 ...

  6. SpringBoot -- 事件(Application Event)

    Spring的事件为Bean与Bean之间的消息通信提供了支持,当一个Bean处理完一个任务之后,希望另外一个Bean知道并能做相应的处理,这时我们就需要让一个Bean监听当前Bean所发送的事件. ...

  7. spring 事件(Application Event)

    spring 事件为bean 与 bean之间传递消息.一个bean处理完了希望其余一个接着处理.这时我们就需要其余的一个bean监听当前bean所发送的事件. spring事件使用步骤如下: 1.先 ...

  8. Spring应用事件(Application Event)

    Spring的事件为Bean与Bean的消息通信提供的支持.当一个Bean处理完了一个任务以后,希望另一个Bean知道并能做出相应的处理,这是我们就需要让另一个Bean监听当前Bean所发送的事件. ...

  9. 事件(Application Event)

    Spring的事件(Appllcation Event)为Bean与Bean之间的消息通信提供了支持.当一个Bean处理完一个任务后,希望另一个Bean知道并能做相应的处理,这种情况可以让另一个Bea ...

随机推荐

  1. bzoj3504: [Cqoi2014]危桥

    题意:给出一个图,有的边可以无限走,有的只能走两次(从一头到另一头为一次),给定两个起点以及对应的终点以及对应要走几个来回,求判断是否能完成. 先来一个NAIVE的建图:直接限制边建为容量1,无限制为 ...

  2. 【Python】【学习笔记】1.快速入门

    1.软件安装 从官网下载相应版本的安装包,一般不大. https://www.python.org/ 安装一路默认即可 2. 参考教程:快速入门:十分钟学会Python 本文的内容介于教程(Totur ...

  3. IOS --- OC与Swift混编

    swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. ...

  4. Eclipse智能提示及快捷键

    1.java智能提示 (1). 打开Eclipse,选择打开" Window - Preferences". (2). 在目录树上选择"Java-Editor-Conte ...

  5. Fragment的startActivityForResult和Activity的startActivityForResult的区别

    2016-08-30 18:22:33 前提:我们的APP要兼容Api level 11以前的,所以必须用FragmentActivity 1.对于Fragment的,我们很多时候都会在Activit ...

  6. 痛苦的vsftpd配置

    1.下载安装:yum install vsftpd 2.添加用户和组(不一定要添加组) group -g 1010 customedname useradd -g customedname -d /h ...

  7. Win7下Hyenae的安装

    (1)下载 链接:http://sourceforge.net/projects/hyenae/   资源:hyenae-0.36-1_fe_0.1-1-win32.exe (2)README --- ...

  8. Visual Studio 不生成.vshost.exe和.pdb文件的方法【转】

    Visual Studio 不生成.vshost.exe和.pdb文件的方法[转] 使用Visual Studio编译工程时,默认设置下,即使选择了「Release」时也会生成扩展名为「.vshost ...

  9. 我的PHP编程环境变迁:notepad -> notepad++ -> Sublime Text2 -> PhpStorm

    10多年前最一开始写PHP程序的时候是用windows自带的notepad,现在想来真的很屌丝. 后来经人推荐换成了notepad++,感觉还是相当不错的(中间还用过一阵子editplus). 比较喜 ...

  10. ScorllView中嵌套listView与Viewpager的焦点问题处理

    解决进入该页面直接显示中的listview而不是从页面最顶端开始显示在setAdapter后调用listview的smoothScrollTo(0,20); 解决listview只能显示一条 需要重写 ...