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接口,而是在具体的需要监听事件的业务类中实现此接口,但是这样还是有一点缺陷,那就是此具体业务类还是会监听到它不关心的事件,不论是用户删除事件还是用户修改事件,没办法,有得必有失,想要方便,肯定会有所牺牲。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值