`
zhangwei_david
  • 浏览: 476981 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring 基于事件的通信

 
阅读更多

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);
			}
		}
	}

 

 

 

1
0
分享到:
评论
3 楼 cywhoyi 2016-02-02  
我现在采用的是RXJava的方式,不过eventbus可能更加舒服点
2 楼 cywhoyi 2016-02-02  
我会是微博 写道
用于什么业务场景?

消息消费等渠道
1 楼 我会是微博 2016-02-01  
用于什么业务场景?

相关推荐

    spring事件的例子

    在Spring框架中,事件处理是一种重要的组件间通信方式。它允许一个对象在完成特定操作后,通知其他对象这一事实,而无需这些对象之间有直接的依赖关系。这种机制基于Java的观察者模式(Observer Pattern),使得松...

    spring 事件处理

    Spring事件处理基于发布/订阅模式,其中事件是消息的载体,而事件监听器则是对这些消息感兴趣的订阅者。在这个场景中,我们将探讨Spring MVC实例与Spring事件处理的结合。 首先,让我们了解Spring MVC。Spring MVC...

    Spring事件管理

    总结来说,Spring的事件管理提供了一种高效且灵活的方式来解耦组件间的通信,通过创建自定义事件、发布事件、监听并处理事件,可以实现复杂业务逻辑中的模块化。在实际开发中,结合`@Async`注解和事件上下文,可以...

    Spring的配置以及事件注入

    总结起来,Spring的配置机制允许我们灵活地定义和管理对象,而事件注入则提供了一种在不同组件间通信的有效途径。了解并熟练掌握这些核心概念,能帮助开发者更好地设计和构建健壮、松耦合的Java应用程序。通过...

    详解Spring事件驱动模型

    首先,Spring事件驱动模型是基于观察者模式实现的,即发布者(Publisher)发布事件,订阅者(Subscriber)监听并处理这些事件。在Spring中,事件对象通常是`ApplicationEvent`的子类,发布事件的方法是`...

    基于O11Auth2和Spring Boot的通信应用.docx

    ..基于O11Auth2和Spring Boot的通信应用.docx

    基于O11Auth2和Spring Boot的通信应用.pdf

    ..基于O11Auth2和Spring Boot的通信应用.pdf

    基于OAuth2和Spring Boot的通信应用.docx

    ### 基于OAuth2和Spring Boot的通信应用 #### OAuth2.0客户端授权与Spring Boot结合的关键知识点 本文档探讨了如何运用OAuth2.0客户端授权方式来构建基于Spring Boot的安全端到端通信应用。该文档对于理解现代网络...

    spring的Applicationcontext对事件的监听,实现类似MQ的效果

    总之,Spring的`ApplicationContext`事件监听功能提供了一种简单但强大的方式来实现内部组件间的通信。通过创建自定义事件、定义监听器以及发布事件,可以在不直接依赖的情况下实现不同服务之间的解耦。这种设计模式...

    基于OAuth2和Spring Boot的通信应用.pdf

    在这个基于OAuth2.0和Spring Boot的通信应用中,我们将探讨如何构建一个端到端的解决方案,特别是针对服务器到服务器的通信场景,这种场景通常不涉及用户界面。 在OAuth2.0的客户端授权模式下,服务之间可以直接...

    spring事件机制

    Spring框架的事件机制是其核心特性之一,它提供了一种基于发布-订阅模式的事件处理方式,使得在Spring应用中的不同组件之间可以进行解耦通信。这个机制允许一个组件(通常是一个服务)触发一个事件,然后其他感兴趣...

    基于SpringCloud的微服务乐优商城

    5. **Spring Cloud Bus**:用于在微服务之间传播事件,例如配置更改,可以实时同步到所有服务实例。 6. **Spring Cloud Data Flow**:数据流处理工具,用于构建和部署数据处理任务。 7. **Spring Cloud Stream**:...

    JAVA-spring学习资源之spring事件

    Spring事件是基于观察者模式实现的,它提供了一种在应用程序组件之间传递信息的方式,而无需这些组件之间有直接的依赖关系。这使得系统更加灵活和可扩展。 1、**Spring事件发布**: 在Spring中,事件通常是一个Java...

    基于Spring Cloud微服务框架整合开发的IM社交系统(Netty即时通讯+Tensorflow+Haar等技术).zip

    基于Spring Cloud,Dubbo,Thrift微服务框架整合开发的IM社交系统(用Netty即时通讯技术+Tensorflow框架+Haar+Adaboost人脸识别技术).zip基于Spring Cloud,Dubbo,Thrift微服务框架整合开发的IM社交系统(用Netty...

    基于Spring的通信(类似于现在的QQ)

    在本项目中,"基于Spring的通信(类似于现在的QQ)"是一个旨在实现企业内部即时通讯功能的软件系统。它利用了Spring框架的强大功能,结合了JSP(Java Server Pages)进行前端展示,Swing用于构建桌面客户端应用,...

    基于Spring Boot框架的移动通信管理系统.zip

    基于Spring Boot框架的移动通信管理系统 项目简介 本项目是一个基于Spring Boot框架开发的移动通信管理系统,旨在提供一个高效、可靠的解决方案来管理移动通信服务。系统包括服务端和客户端,通过权限登录机制...

    基于Spring-Boot和Spring-Cloud实现微服务架构学习(一).doc

    5. **Spring Cloud Bus**:事件、消息总线,用于服务间的通信。 6. **Spring Cloud LoadBalancer**:负载均衡器,如Ribbon,用于客户端的负载均衡。 7. **Spring Cloud Sleuth**:分布式追踪解决方案,如与Zipkin或...

    基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip

    基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式...

    基于SpringCloud的电商项目

    这包括如何使用SpringCloud来搭建服务注册与发现、负载均衡、熔断机制、API网关、微服务间的通信等关键功能。通过分析源码,我们可以了解到如何在实际项目中运用这些技术,从而提升我们的微服务开发技能。 【标签】...

    基于Netty通信框架和Kryo序列化协议的Spring集成Nexus RPC框架设计源码

    该项目为基于Netty通信框架和Kryo序列化协议的Spring集成Nexus RPC框架设计源码,共计90个文件,涵盖70个Java源文件、8个XML配置文件、2个YAML文件、2个PNG图片文件、1个Git忽略文件、1个许可证文件和1个Markdown...

Global site tag (gtag.js) - Google Analytics