`

spring的事件 处理机制

阅读更多

基于SPRING的事件处理其实很简单,初学者不必一开始就担心搞不懂,本文先是介绍完全基于SPRING的事件监听实现(熟识Spring事件监听的朋友应该跳过第一节),然后依葫芦画瓢自已做一个性能更好事件监听小框架,最后在回贴中加入了注解版。 
    为何要使用事件监听,而不是直接调用?打个比方,在系统删除一个用户时,需要把用户的其他信息和行为记录一起删除,此时最容易想到的是:删除用户时,调用其他Service类接口删除与之相关的信息和用户行为记录,但是用户是一个基础模块,随着系统模块不断增加,会有越来越多的模块与之关联,按以上方案,每增加一个与用户相关的模块,那么删除用户时就要把这个模块的信息也一起删除,这样用户这个模块就与这些业务模块偶合在一起了,只要系统不断的增加或减少模块,用户模块就永远都改不完。(以上逻辑仅为说明问题) 
    如果采用事件监听,那么在删除一个用户时,发布一事件就完事了,所有相关的模块监听此事件,在事件处理中删除本模块对应的数据,那么用户模块也不会与这些模块有任何偶合了。 
    好,回到主题, 
    1、完全基于SPRING的事件监听与处理: 
    首先,SERVICE总接口类继承org.springframework.context.ApplicationListener接口,并且在SERVICE的抽象类中实现此接口的方法,SERVICE总接口代码: 

Java代码 
  1. import org.springframework.context.ApplicationListener;  
  2.   
  3. /** 
  4.  * 业务层顶层接口 
  5.  */  
  6. public interface IBaseService extends ApplicationListener{  
  7.   
  8. }  



SERVICE抽象类代码,所有具体业务类皆继承此抽象业务类

Java代码 
  1. import org.springframework.context.ApplicationEvent;  
  2.   
  3. /** 
  4.  * 实现顶层接口的抽象类 
  5.  */  
  6. public abstract class AbstractBaseService implements IBaseService {  
  7.   
  8.   
  9.     /** 
  10.      * 此方法不允许重写,要监听事件,重写onBaseEvent方法 
  11.      */  
  12.     public final void onApplicationEvent(ApplicationEvent event) {  
  13.         if (event instanceof BaseEvent) {  
  14.             onBaseEvent((BaseEvent) event);  
  15.         }  
  16.     }  
  17.   
  18.     /** 
  19.      * 要监听事件就重写此方法 
  20.      */  
  21.     protected void onBaseEvent(BaseEvent event) {  
  22.     }  
  23.   
  24.          /** 
  25.      * 发布事件 
  26.      */  
  27.     protected final void publishEvent(BaseEvent event) {  
  28.         //取得SPRING容器并发布事件  
  29.         org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext().publishEvent(event);  
  30.     }  
  31. }  


BaseEvent类是我自定义的一个类,各业务模块要发布事件,首先定义自已的EVENT类,继承BaseEvent。BaseEvent类代码

Java代码 
  1. import org.springframework.context.ApplicationEvent;  
  2.   
  3. public class BaseEvent extends ApplicationEvent {  
  4.   
  5.     public BaseEvent(Object source) {  
  6.         super(source);  
  7.     }  
  8.   
  9. }  



用户业务类UserSerivceImpl删除一个用户时,需要发布事件,所以要先定义一个UserDeleteEvent事件类

Java代码 
  1. import com.esc.permission.model.User;  
  2.   
  3. public class UserDeleteEvent extends BaseEvent {  
  4.       
  5.     public UserDeleteEvent(User user){  
  6.         super(user);  
  7.     }  
  8.       
  9.     public User getUser(){  
  10.         return (User) super.getSource();  
  11.     }  
  12.   
  13. }  


下面是UserSerivceImpl类删除用户的方法模拟

Java代码 
  1. public void deleteUser(String id){  
  2.     //先发布删除事件  
  3.     publishEvent(new UserDeleteEvent(new User(id)));  
  4.     //再把用户删除  
  5.     userDao.deleteUser(id);  
  6. }  


假如有一个OtherServiceImpl业务类需要接收用户删除事件并做一些处理,

Java代码 
  1. public class OtherServiceImpl extends AbstractBaseService {  
  2.     private IBaseDAO otherDao;  
  3.   
  4.     /** 
  5.      * 重写父类的方法,处理用户删除事件 
  6.      */  
  7.     protected void onBaseEvent(BaseEvent baseEvent){  
  8.         if(baseEvent instanceof UserDeleteEvent){//如果是用户删除事件  
  9.             otherDao.deleteOtherData(((User)baseEvent.getSource()).getId());  
  10.         }  
  11.     }  
  12. }  


    到此,所有逻辑就完了,用户业务类中根本不需要知道谁将会处理此事件,所以完全与其它模块解偶了。 
    这里用了一个偷懒的方法,那就是在业务类的顶层接口IBaseService中实现了ApplicationListener接口,这样其实所有具体业务类都参与了所有事件的处理,即使是那些根本不需要监听事件的业务类。对于所有根本不需要监听事件的业务类,事件发生时就调用其父类空方法onBaseEvent,这里有一点性能浪费,如果改进?不要在顶层接口IBaseService中实现ApplicationListener接口,而是在具体的需要监听事件的业务类中实现此接口,但是这样还是有一点缺陷,那就是此具体业务类还是会监听到它不关心的事件,不论是用户删除事件还是用户修改事件,没办法,有得必有失,想要方便,肯定会有所牺牲。 

分享到:
评论

相关推荐

    深入探索Spring事件监听机制:技术与应用

    除此之外,Spring也支持自定义事件,提供灵活性来处理特定业务需求。 事件监听器是对事件响应的处理器。它们可以通过实现ApplicationListener接口或使用@EventListener注解来定义。这些监听器关注特定类型的事件,...

    EventBus与Spring Event区别详解(EventBus 事件机制,Spring Event事件机制)

    主要介绍了EventBus与Spring Event区别,需要的朋友可以参考下

    深入理解spring的事务管理机制

    【免费】深入描述spring的事务处理机制,很不错的资源。

    Spring Boot的Spring事务处理机制4大特性.docx

    事务的4大特性 原子性(Atomicity) 一个事务要么全部提交成功,要么全部失败回滚,不能只执行其中的一部分操作。 一致性(Consistency) 一旦事务完成(不管成功还是失败),系统必须确保涉及的数据处于一致的状态,而...

    Spring-batch Demo

    JobLaunch用来启动Job,JobRepository是上述处理提供的一种持久化机制,它为JobLauncher,Job,和Step实例提供CRUD操作。 外部控制器调用JobLauncher启动一个Job,Job调用自己的Step去实现对数据的操作,Step处理...

    Java异常介绍及Spring Boot统一异常处理

    Spring Boot 提供了统一的异常处理机制,通过使用 @ControllerAdvice 和 @ExceptionHandler 注解,可以实现对控制器层、Service 层、Dao 层以及 Spring 系统内定义的部分异常的统一处理。 在 Spring Boot 中,可以...

    spring事件扩展

    机制通知异常监听器进行处理。在笔者的一个项目中,就曾经借助事件机制,较好的实现了当系统 异常时在监视终端上报警,同时发送报警SMS至管理员手机的功能。 */ public class LoginAction implements ...

    Spring开发指南

    Spring Bean封装机制 Bean Wrapper Bean Factory ApplicationContext Web Context Spring 高级特性 Web 应用与 MVC Spring MVC Spring MVC指南 基于模板的Web表示层技术 Web 应用中模板技术与 JSP 技术的...

    Java Spring框架面试题大全

    开发者可以自定义事件类和事件监听器,并通过应用程序上下文的publishEvent方法来发布事件,Spring框架会自动分发事件给所有对该事件感兴趣的监听器进行处理。事件监听机制帮助开发者更好地解耦代码,提高应用程序的...

    Spring-Reference_zh_CN(Spring中文参考手册)

    3.8.2. 事件 3.8.3. 底层资源的访问 3.8.4. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.9.1. 使用Singleton-helper类 4. 资源 4.1. 简介 4.2. Resource 接口 4.3. 内置 Resource 实现...

    开源框架 Spring Gossip

    从代理机制初探 AOP 动态代理 <br>AOP 观念与术语 Spring AOP Advices Advices 包括了Aspect 的真正逻辑,由于缝合至Targets的时机不同,Spring 提供了几种不同的 Advices。 Before ...

    Spring 2.0 开发参考手册

    3.8.2. 事件 3.8.3. 底层资源的访问 3.8.4. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.9.1. 使用Singleton-helper类 4. 资源 4.1. 简介 4.2. Resource 接口 4.3. 内置 ...

    Spring Security OAuth2.0学习笔记.zip

    别处理什么,如何自定义这些组件满足个性需求。 OAuth2.0认证的四种模式?它们的大体流程是什么? Spring cloud Security OAuth2包括哪些组件?职责? 分布式系统认证需要解决的问题? 掌握学习方法,掌握思考方式。

    使用Spring更好地处理Struts动作

    Spring 还提供了一种使用面向方面代码代替正常的面向对象代码的简单机制。 Spring AOP 允许您使用拦截器 在一个或多个执行点上拦截应用程序逻辑。加强应用程序在拦截器中的日志记录逻辑会产生一个更可读的、实用的...

    spring_exception异常处理

    好多项目都有容错机制 后台服务器报错后 不是讲错误信息直接发给用户 而是发送一个其他页面 你在上网的时候应该遇到过后台出错了 用户看到的页面是一个小孩在哭 提示页面找不到什么的

    JSF+Spring+JPA(Hibernate实现)的环境搭建

    JSF更贴近事件比较多的web前端处理机制。想想我们一般要接收和处理页面的各种事件是用什么:js函数+ajax处理是吧(Flex我没有接触过,不知道它是怎么样的处理前后台交互的)。JSF可以采用事件监听机制,控件(JSF...

    Spring中文帮助文档

    3.8.3. 事件 3.8.4. 底层资源的访问 3.8.5. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.10. 以J2EE RAR文件的形式部署Spring ApplicationContext 3.11. 基于注解(Annotation-...

    spring chm文档

    3.8.2. 事件 3.8.3. 底层资源的访问 3.8.4. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.9.1. 使用Singleton-helper类 4. 资源 4.1. 简介 4.2. Resource 接口 4.3. 内置 ...

    从零开始学Spring Boot

    1.40 Spring Boot集成EHCache实现缓存机制 1.41 Spring Boot分布式Session状态保存Redis 1.42 Spring Boot Shiro权限管理 1.43 Spring Boot Shiro权限管理 1.44 Spring Boot Shiro权限管理 1.45 Spring Boot Shiro...

Global site tag (gtag.js) - Google Analytics