spring 事件驱动 以及线程分离

来源:互联网 发布:一键4g网络解锁助手 编辑:程序博客网 时间:2024/06/04 18:58

Spring事件模型事件驱动模型是一种观察者模式的典型应用,或者叫发布——订阅模型,Java中awt的事件机制和Spring的事件机制都是观察者模式的应用。一般都是发布者有更改变动时,订阅者会接收到发布者的变动通知。举个通用的例子网上看新闻,首先我们需要去订阅新闻,当有新的新闻时,网站会自动推送新闻给已经订阅过该新闻的用户

下面一个两个例子
第一个例子非线程分离

import org.springframework.context.ApplicationEvent;public class TestEvent extends ApplicationEvent {    private static final long serialVersionUID = 1L;    private String message;    public TestEvent(Object source) {        super(source);    }    public TestEvent(Object source,String message) {        super(source);        this.message=message;    }    public void print(String threadName){    System.out.println(threadName+"....."+this.message+"......");    }}
import org.springframework.context.ApplicationEvent;import org.springframework.context.ApplicationListener;public class TestListener implements ApplicationListener<ApplicationEvent>{    @Override    public void onApplicationEvent(ApplicationEvent event) {        if(event instanceof TestEvent){            TestEvent testevent=(TestEvent)event;            testevent.print(Thread.currentThread().getName());        }    }}
import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.ApplicationEvent;public class AppUtil implements ApplicationContextAware {    private static ApplicationContext appContext;    @Override    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        appContext = applicationContext;    }    public static Object getBean(String paramString) {        return appContext.getBean(paramString);    }    public static void sendEvent(ApplicationEvent event){        appContext.publishEvent(event);    }}
public static void main(String[] args) {        ApplicationContext ctx=new ClassPathXmlApplicationContext("spring-context2.xml");        AppUtil.sendEvent(new TestEvent("", "message!!!"));    }
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"    xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd      http://www.springframework.org/schema/aop      http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">    <bean id="appUtil" class="com.eroadsf.springdemo.applicationAware.AppUtil" />    <bean id="testListener" class="com.eroadsf.springdemo.applicationAware.TestListener"></bean></beans>

最后结果
main…..message!!!……

下面的例子增加一个事件监听器

public class TestListener1 implements ApplicationListener<ApplicationEvent>{    @Override    public void onApplicationEvent(ApplicationEvent event) {        if(event instanceof TestEvent){            TestEvent testevent=(TestEvent)event;            testevent.print(Thread.currentThread().getName());        }    }}

配置文件增加一个监听器

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"    xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd      http://www.springframework.org/schema/aop      http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">    <bean id="appUtil" class="com.eroadsf.springdemo.applicationAware.AppUtil" />    <bean id="testListener" class="com.eroadsf.springdemo.applicationAware.TestListener"></bean>    <bean id="testListener1" class="com.eroadsf.springdemo.applicationAware.TestListener1"></bean></beans>

结果都是由main线程输出

main.....message!!!......main.....message!!!......

假设这个场景是一个支付,2个监听器 一个是邮件发送一个是短信发送,并且在同一个事务中,如果短信发送出现异常可能连支付操作都回滚了。

所以spring采取了线程分离技术
我们将配置文件修改如下:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"    xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd      http://www.springframework.org/schema/aop      http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">    <bean id="appUtil" class="com.eroadsf.springdemo.applicationAware.AppUtil" />    <bean id="testListener" class="com.eroadsf.springdemo.applicationAware.TestListener"></bean>    <bean id="testListener1" class="com.eroadsf.springdemo.applicationAware.TestListener1"></bean>    <!-- 测试Spring事件机制 异步发布事件 -->     <bean id="taskExecutor"        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">        <property name="corePoolSize" value="5"></property>    </bean>    <bean id="applicationEventMulticaster"        class="org.springframework.context.event.SimpleApplicationEventMulticaster">        <property name="taskExecutor" ref="taskExecutor"></property>    </bean> </beans>

最后的输出结果看到是两个不同的线程输出的而且不是main线程

taskExecutor-3.....message!!!......taskExecutor-4.....message!!!......

这是因为SimpleApplicationEventMulticaster里增加了线程池的处理一个监听开一个线程执行onApplicationEvent(event);

@Override    @SuppressWarnings({ "unchecked", "rawtypes" })    public void multicastEvent(final ApplicationEvent event) {        for (final ApplicationListener listener : getApplicationListeners(event)) {            Executor executor = getTaskExecutor();            if (executor != null) {                executor.execute(new Runnable() {                    @Override                    public void run() {                        listener.onApplicationEvent(event);                    }                });            }            else {                listener.onApplicationEvent(event);            }        }    }
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小学生做题粗心怎么办 审题总是不认真怎么办 好学生批评了怎么办 地生会考没考好怎么办 一年级孩子抄作业怎么办 孩子抄作业慢怎么办 孩子撒谎抄作业怎么办 孩子不肯做作业怎么办? 同桌抄我答案怎么办 初中孩子抄作业怎么办 小孩子做题马虎怎么办 数学做题马虎怎么办 小朋友做题粗心怎么办 孩子老是落题怎么办 脑子笨反应慢怎么办 脑子笨的人怎么办 孩子学习反应慢怎么办 孩子学习不入门怎么办 高三出现厌学怎么办 天生笨的人怎么办 学生考试粗心该怎么办 高三学生失眠怎么办 期末考试考差了怎么办 小孩考试太粗心怎么办 带孩子太粗心怎么办 小孩做数学粗心怎么办 小学一年级学生厌学怎么办 小学二年级厌学怎么办 做题做的烦躁了怎么办 英语不会做题怎么办 孩子审题不细心怎么办 生孩子有恐惧症怎么办 小孩不喜欢上幼儿园怎么办 小孩不喜欢去幼儿园怎么办 小孩不喜欢学生字怎么办 学生不喜欢补课老师怎么办 小孩不喜欢上学逃课怎么办 一年级小朋友不爱写字怎么办 幼儿园小朋友不爱写字怎么办 孩子懒散不积极怎么办 孩子不肯上幼儿园怎么办