Spring 应用上下文支持基于事件的Bean间通信。在基于事件的通信模式中,事件的发送者不需要关系,事件的监听者。这样可以使消息的发送者和监听者进行解耦。
在Spring中所有事件类必须继承自ApplicationEvent,这样任何bean都可以调用事件发布者的publishEvent()方法,发布一个事件。
public class MyEvent extends ApplicationEvent { /** */ private static final long serialVersionUID = 1L; /** * @param source */ public MyEvent(Object source) { super(source); } }
@Component("eventPublisher") public class EventPublisher implements ApplicationEventPublisherAware { private ApplicationEventPublisher applicationEventPublisher; public void ckeckout(){ applicationEventPublisher.publishEvent(new MyEvent(this)); } /** * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher) */ @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher=applicationEventPublisher; } }
@Component public class MyListener implements ApplicationListener<MyEvent> { /** * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) */ @Override public void onApplicationEvent(MyEvent event) { System.out.println(Thread.currentThread().getName()+";"+event.getTimestamp()); } }
public class Test { /** * * @param args * @author zhangwei<wei.zw@corp.netease.com> */ public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); EventPublisher cashier = (EventPublisher) context.getBean("eventPublisher"); for(int i=0;i<20;i++) { cashier.ckeckout(); } } }
<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>
taskExecutor-1;1454033201241 taskExecutor-2;1454033201242 taskExecutor-3;1454033201242 taskExecutor-4;1454033201242 taskExecutor-5;1454033201243 taskExecutor-1;1454033201243 taskExecutor-3;1454033201243 taskExecutor-3;1454033201243 taskExecutor-2;1454033201243 taskExecutor-5;1454033201243 taskExecutor-1;1454033201243 taskExecutor-4;1454033201243 taskExecutor-3;1454033201243 taskExecutor-2;1454033201244 taskExecutor-5;1454033201244 taskExecutor-5;1454033201244 taskExecutor-4;1454033201244 taskExecutor-3;1454033201244 taskExecutor-2;1454033201244 taskExecutor-5;1454033201244
通过上面的一个示例,实现了异步的基于事件通信。
在AbstractApplicationContext中发布事件的实现如下,首先获取applicationEventMulticaster,通过其发布事件。
/** * Publish the given event to all listeners. * <p>Note: Listeners get initialized after the MessageSource, to be able * to access it within listener implementations. Thus, MessageSource * implementations cannot publish events. * @param event the event to publish (may be application-specific or a * standard framework event) */ public void publishEvent(ApplicationEvent event) { Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } getApplicationEventMulticaster().multicastEvent(event); if (this.parent != null) { this.parent.publishEvent(event); } }
在看看ApplicaitonEventMulticaster的初始化逻辑,如果在有配置过applicationEventMulticaster则直接使用,否则创建一个;注意,配置是ID必须是applicationEventMulticaster
/** * Initialize the ApplicationEventMulticaster. * Uses SimpleApplicationEventMulticaster if none defined in the context. * @see org.springframework.context.event.SimpleApplicationEventMulticaster */ protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 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 { 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 + "]"); } } }
再看看ApplicationEventMulticaster中又是如何发布事件的。如果有配置线程池,则异步处理,否则同步处理。
public void multicastEvent(final ApplicationEvent event) { for (final ApplicationListener listener : getApplicationListeners(event)) { Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(new Runnable() { @SuppressWarnings("unchecked") public void run() { listener.onApplicationEvent(event); } }); } else { listener.onApplicationEvent(event); } } }
相关推荐
基于OAuth2和Spring Boot的通信应用.pdf基于OAuth2和Spring Boot的通信应用.pdf基于OAuth2和Spring Boot的通信应用.pdf基于OAuth2和Spring Boot的通信应用.pdf基于OAuth2和Spring Boot的通信应用.pdf基于OAuth2和...
基于OAuth2和Spring Boot的通信应用.docx基于OAuth2和Spring Boot的通信应用.docx基于OAuth2和Spring Boot的通信应用.docx基于OAuth2和Spring Boot的通信应用.docx基于OAuth2和Spring Boot的通信应用.docx基于OAuth2...
基于Spring的企业内部通信软件,结合JSP,swing,socket的内部通信软件
毕设项目基于Spring + Spring MVC + Mybatis的销售管理系统源码.zip毕设项目基于Spring + Spring MVC + Mybatis的销售管理系统源码.zip毕设项目基于Spring + Spring MVC + Mybatis的销售管理系统源码.zip毕设项目...
内容概要:通过带着读者拟开发基于SpringCloud 微服务架构的房屋租售平台,为房屋的供需两房提供便捷高效的平台的同时,也为其设置了良好的沟通模块,便于双方能够合理而满意地进行交易,提高居住的幸福感。...
消息管理模块主要包括消息通知、即时通信两个模块。社交模块主要包括文章、问答、招聘、活动、吐槽等模块。采用 Docker 容器化部署方案, 融合了 Deeplearning4j 智能分类框架、Webmagic 爬虫框架、RabbitMQ、...
基于Spring Boot的社区论坛源码.zip毕业设计-基于Spring Boot的社区论坛源码.zip毕业设计-基于Spring Boot的社区论坛源码.zip毕业设计-基于Spring Boot的社区论坛源码.zip毕业设计-基于Spring Boot的社区论坛源码....
它使用 Spring Boot 框架来构建后端服务,并提供了 RESTful API 接口以与前端或其他客户端进行通信。 以下是创建基于 Spring Boot 的设备管理系统的一般步骤: 确保已安装 Java 开发环境:在开始之前,确保您已...
2、使用spring的事件传播机制实现bean与bean之间基于事件驱动的通信 3、自定义注解、组合注解 相关资料参考我写的博文:http://blog.csdn.net/jayjjb/article/details/70906511 1个最佳实践1分,很划算的^_^
资源名字:基于Springcloud+mysql的分布式架构网上商城设计与实现(源码+设计文档+部署说明+视频演示).zip 资源内容:项目全套源码+完整文档 源码说明: 全部项目源码都是经过测试校正后百分百成功运行。 基于...
本文在考虑到以上的问题的基础上,利用大学期间中所学到的的专业知识,独立开发一个基于Spring Boot和vue.js的校园食堂订餐系统。论文首先进行了系统功能的总体设计,使本系统具有以下主要功能:一是具有手机端让...
基于SpringMVC+Spring3+Mybatis框架的OA项目.zip基于SpringMVC+Spring3+Mybatis框架的OA项目.zip基于SpringMVC+Spring3+Mybatis框架的OA项目.zip基于SpringMVC+Spring3+Mybatis框架的OA项目.zip基于SpringMVC+Spring...
基于SpringMVC+Spring+MyBatis+Maven项目案例.zip基于SpringMVC+Spring+MyBatis+Maven项目案例.zip基于SpringMVC+Spring+MyBatis+Maven项目案例.zip基于SpringMVC+Spring+MyBatis+Maven项目案例.zip基于SpringMVC+...
毕设源码-基于spring boot + element-ui的后台管理系统.zip毕设源码-基于spring boot + element-ui的后台管理系统.zip毕设源码-基于spring boot + element-ui的后台管理系统.zip毕设源码-基于spring boot + element-...
能学到什么:①前后端分离架构、微服务架构、Spring框架、Vue 框架、隧道设备通信方式是怎么在系统中体现的;②用户管理模块、环境采集模块、设备调节模块、视频监控模块、注册中心配置模块、状态更新和数据恢复模块...
Java开发基于SpringCloud的校园小店商城系统源码.zipJava开发基于SpringCloud的校园小店商城系统源码.zipJava开发基于SpringCloud的校园小店商城系统源码.zipJava开发基于SpringCloud的校园小店商城系统源码.zipJava...
基于Spring Cloud和ArcFace SDK的人脸识别智能会议室管理系统源码.zip 基于Spring Cloud和ArcFace SDK的人脸识别智能会议室管理系统源码.zip 基于Spring Cloud和ArcFace SDK的人脸识别智能会议室管理系统源码.zip ...
基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式...
一个基于Spring Boot + WebSocket + Redis,可快速开发的分布式即时通讯群聊系统。适用于直播间聊天、游戏内聊天、客服聊天等临时性群聊场景。 Java开发基于SpringBoot+WebSocket+Redis分布式即时通讯群聊系统。一...
毕业设计基于spring+springMVC+mybatis的仓库管理系统源码.zip毕业设计基于spring+springMVC+mybatis的仓库管理系统源码.zip毕业设计基于spring+springMVC+mybatis的仓库管理系统源码.zip毕业设计基于spring+...