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); } } }
阅读全文
0 0
- spring 事件驱动 以及线程分离
- 单线程、多线程以及事件驱动编程模型对比
- Spring事件驱动模型
- spring 事件驱动模型
- spring事件以及监听
- Javascript事件相关操作以及行为事件分离
- Spring事件驱动模型详解
- 详解Spring事件驱动模型
- 详解Spring事件驱动模型
- 详解Spring事件驱动模型
- 详解Spring事件驱动模型
- spring 事件驱动模型简介
- 详解Spring事件驱动模型
- 详解Spring事件驱动模型
- 详解Spring事件驱动模型
- Java事件驱动模式,Spring事件
- 线程同步消费事件-spring
- java基于事件驱动之spring事件驱动
- MySQL配置文件my.cnf参数优化和中文详解
- Android中的回车键实现搜索
- Linux系统超级用户root密码忘记的解决办法
- serio总线------虚拟键盘驱动--键盘中断
- linux下二进制编辑方法
- spring 事件驱动 以及线程分离
- LTP 第三章 开发系统调用测试集
- 字节流与字符流
- man 命令
- Leetcode 464 can i win
- Javafx FXMLLoader的一个坑
- 多进程和多线程的比较
- <10/9>打卡随笔
- 用代码获取unity打包安卓apk的md5值