事件监听处理小框架
来源:互联网 发布:蒙古音乐软件 编辑:程序博客网 时间:2024/04/30 23:01
1、定义注解类
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface HandleEvent {
- Class<? extends BaseEvent>[] events();
- }
2、在顶层接口IBaseService增加一个方法getRealClass,此方法用于返回真正的业务类字节码引用,此方法在抽象业务类用统一实现即可。本来不需要此方法,但由于使用了SPRING的AOP,一时没有找到取得真正业务类字节码引用的方法,所以才定义这么个接口,代码
- /**
- * 业务层顶层接口,自定义的小框架里可以在顶层业务接口中直接继承事件接口,不影响性能
- * 因为在初始化事件监听器时,已经过滤了没有真正实现接口方法的类,所以不会造成多余的调用
- */
- public interface IBaseService extends IBaseEventListener{
- public Class<? extends IBaseService> getRealClass();
- }
抽象业务类的代码
- /**
- * 实现顶层接口的抽象类
- */
- public abstract class AbstractBaseService implements IBaseService{
- /**
- * 发布事件 2008-9-18
- */
- protected void publishEvent(BaseEvent event) {
- EventController.publishEvent2(event);
- }
- //具体子类中不需要再实现
- public Class<? extends IBaseService> getRealClass(){
- return this.getClass();
- }
- public void onBaseEvent(BaseEvent event){
- //这里空实现,且没有注解,这样,如果具体业务类没有重写方法,
- //初始化事件监听器时就会被过滤掉,不会造成多余调用
- }
- }
改写IBaseEventListener接口,删除getEventClasses方法,因为使用注解来定义要处理事件,所以此方法不再需要。本来onBaseEvent方法也可以去除,直接由注解来定义即可,但由于以下原因,还是要保留:1、如果没有任何接口定义onBaseEvent方法,那么SPRING的代理类也不会有此方法,这样就无法使用AOP的种种好处了;2、为规范事件处理的方法名和参数,更易于后续维护,所以还是要有个接口定义为好。
- /**
- * 事件处理接口,实现此接口并且getEventClasses方法的返回结果条数大于0,方可处理对应的事件
- */
- public interface IBaseEventListener {
- /**
- * 事件处理的方法
- */
- public void onBaseEvent(BaseEvent event);
- }
事件处理工具类
- /**
- * 事件处理相关操作工具类
- */
- public class EventController {
- private static Map<String,List<LisenerInfo>> listeners2 = new LinkedHashMap<String, List<LisenerInfo>>();
- /**
- * 扫瞄所有bean,进行事件监听
- */
- public static void initBaseEventListener2(){
- //取得所有业务类
- Map<String,IBaseService> beans = SysContext.getBeansOfType(IBaseService.class);
- if(beans==null || beans.size()==0)
- return;
- Collection<IBaseService> values = beans.values();
- for (IBaseService listener : values) {
- //注意这里不能使用listener.getClass()方法,因此方法返回的只是SPRING的代理类,此代理类的方法没有注解信息
- Method[] methods = listener.getRealClass().getDeclaredMethods();
- for (Method method : methods) {
- //判断方法中是否有指定注解类型的注解
- boolean hasAnnotation = method.isAnnotationPresent(HandleEvent.class);
- if (hasAnnotation) {
- //根据注解类型返回方法的指定类型注解
- HandleEvent annotation = method.getAnnotation(HandleEvent.class);
- Class<? extends BaseEvent>[] events = annotation.events();
- if(events==null || events.length==0){//这里过滤掉没有真正实现事件监听的业务类
- continue;
- }
- for (int i = 0; i < events.length; i++) {
- try {
- if(listeners2.containsKey(events[i].getName())){
- //注意这里要用代理类的方法,即listener.getClass().getMethod(method.getName()),不能直接使用method变量,下同
- listeners2.get(events[i].getName()).add(new LisenerInfo(listener,listener.getClass().getMethod(method.getName())));
- }else{
- listeners2.put(events[i].getName(),Arrays.asList(new LisenerInfo[]{new LisenerInfo(listener,listener.getClass().getMethod(method.getName()))}));
- }
- } catch (Exception e) {
- throw new UnknowException("初始化事件监听器时出错:",e);
- }
- }
- }
- }
- }
- }
- /**
- * 发布事件
- */
- public static void publishEvent2(BaseEvent event){
- List<LisenerInfo> list = listeners2.get(event.getClass().getName());
- if(list!=null && list.size()>0){
- for (LisenerInfo listener : list) {
- try {
- listener.getMethod().invoke(listener.getService(), event);
- } catch (Exception e) {
- //此处不能捕捉异常,因为任何一个处理类实例出错都应该全部回滚
- throw new UnknowException(e);
- }
- }
- }
- }
- }
- //此类记录目标方法和目标类
- class LisenerInfo{
- private Method method;//目标方法
- private Object service;//业务类实例
- public LisenerInfo(Object service,Method method){
- this.method = method;
- this.service = service;
- }
- public Method getMethod() {
- return method;
- }
- public Object getService() {
- return service;
- }
- }
好了,框架完成,事件发布还和以前那样,来看看事件处理的实现,同样也不再需要getEventClasses方法了
- //不再需要每个具体业务都实现IBaseEventListener接口
- public class OtherServiceImpl extends AbstractBaseService implements OtherService{
- private IBaseDAO otherDao;
- /**
- * 重写父类的方法,处理用户删除事件
- */
- @HandleEvent(events={UserDeleteEvent.class,UserUpdateEvent.class})
- public void onBaseEvent(BaseEvent baseEvent){
- if(baseEvent instanceof UserDeleteEvent){//如果是用户删除事件
- otherDao.deleteOtherData(((User)baseEvent.getSource()).getId());
- }else{
- //....
- }
- }
- }
- 事件监听处理小框架
- 事件监听处理小框架
- Java 事件和监听器 监听处理小框架
- 自己做的事件监听处理小框架
- ExtJS07:事件监听处理
- Android 事件监听处理
- 事件监听处理
- Android 事件监听处理
- 事件处理函数/监听函数
- Session监听事件的处理
- android 监听事件的处理
- 基于监听的事件处理
- android 处理双击事件监听
- 事件的监听和处理
- android 事件监听处理机制
- Android事件监听及处理
- 事件处理函数/监听函数/事件对象
- Android事件处理之监听事件
- 再谈java事件监听机制
- const常量的修改问题
- JAVA用户自定义事件监听完整例子
- VC基本操作四十条
- 自己写的俄罗斯方块
- 事件监听处理小框架
- 100个开源或免费的功能测试工具
- asterisk 使用 g729 g723
- Java异常处理总结
- Makefile
- VC中实现FTP功能
- [转] ubuntu apache2配置
- pdf 和 word的相互转化
- 监听者模式:(Swing监听器竟然是二叉树!!牛比!)