3、注解版实现:
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(),createList(new LisenerInfo(listener,listener.getClass().getMethod(method.getName()))));
}
} catch (Exception e) {
throw new UnknowException("初始化事件监听器时出错:",e);
}
}
}
}
}
}
private static List<LisenerInfo> createList(LisenerInfo li){
List<LisenerInfo> list = new ArrayList<LisenerInfo>(5);
list.add(li);
return list;
}
/**
* 发布事件
*/
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{
//....
}
}
}
全部完成
分享到:
相关推荐
在Spring框架中,事件监听是一种实现模块间解耦的有效手段,它允许我们在应用程序的不同部分之间传递消息,而无需直接依赖。本篇文章将详细介绍Spring事件监听的三种方式:基于接口的监听器、基于类的监听器以及基于...
8. **事件监听**:Spring框架允许通过监听器接口来响应容器内的事件,如bean的创建和销毁。手动实现的版本可能会包含类似的事件触发和处理机制。 通过这个项目,开发者可以深入了解Spring框架的内部工作原理,这...
在本精简版中,开发者宣称已将框架进行了优化,去除了不必要的复杂性,并采用了纯注解的方式,旨在提供一个更加简洁、易于上手的环境。 首先,Spring框架是核心,它提供了依赖注入(DI)和面向切面编程(AOP)的功能。...
在SSH全注解版中,Hibernate的注解使得数据库表与Java类的映射更加直观。`@Entity`注解标记实体类,`@Table`定义表名,`@Column`对应列名,`@GeneratedValue`管理自增主键,`@OneToMany`、`@ManyToOne`、`@OneToOne`...
只需在方法上添加相应的注解,就能实现事件监听,大大减少了事件处理代码。 ### 5. 与 Eclipse 集成 虽然现在许多开发者转向了 Android Studio,但 `eclipse-java-luna` 版本的 Eclipse 仍然是一个可靠的开发环境...
总之,Android Butter Knife注解框架是提升开发效率和代码质量的一个利器,通过注解的方式简化了UI元素的查找和事件处理,让开发者能更专注于业务逻辑,而不是基础的视图操作。虽然现在有更先进的替代方案,但理解并...
为了实现更高级的客户端UI组合,ZK框架提供了客户端事件监听机制,允许开发者通过JavaScript和ZK的组件模型来进行交互式操作。事件监听、事件触发、事件转发以及事件队列的概念被详细解释,以及如何在MVC(Model-...
### 基于全注解方式的SSH基础框架解析 #### 概述 本文将详细介绍一个基于Struts2、Spring、Hibernate以及Hibernate Generic DAO构建的基础框架。该框架使用全注解的方式进行配置,并且提供了清晰的包结构和文档,...
本文将详细介绍如何利用AndroidAnnotations框架优雅地实现ListView功能。 AndroidAnnotations是一个基于注解的Java库,它通过预编译处理来消除Android开发中的样板代码,提高代码的可读性和可维护性。在本例子中,...
JUnit5是Java编程语言中最流行的单元测试框架之一,它的最新版本带来了许多改进和新特性。在"junit5 监听器工程"中,我们主要关注的是如何利用JUnit5的监听器来收集和处理测试结果。这个压缩包可能包含了所有必要的...
SSH三大框架指的是Spring、Struts和Hibernate,它们是Java Web开发中的主流框架,极大地提高了开发效率和代码质量。本文将详细介绍在使用注解方式进行整合时所需的jar包,并提供相关知识背景。 Spring框架是一个...
6. **异步事件监听**:4.4.0版本引入了异步事件监听器,允许开发者在不阻塞主线程的情况下执行复杂的业务逻辑,提高应用并发性能。 7. **HQL和JPQL的改进**:在查询语言方面,4.4.0版本修复了许多已知问题,并添加...
除了这些基础功能,Jet库可能还包含了其他高级特性,如事件监听的注解处理、依赖注入支持等。例如,我们可以通过`@Click`注解为按钮添加点击事件监听,无需再写匿名内部类。此外,可能还有针对生命周期方法的注解,...
3. **eventListener**:在Java代码中定义事件监听器,处理特定事件。 4. **action**:通过`<action>`标签或`@Listen`注解处理动作事件。 **六、学习资料** 除了本文提供的信息外,还有更多官方文档、教程和示例...
- **Model**:负责存储和处理数据,可以广播事件,监听框架事件。 - **View**:展示数据,通过Mediators与Model交互。 - **Controller**:管理命令,处理来自View的请求,协调Model和Service。 - **Service**:处理...
除了上述核心注解,SSH框架还提供了许多其他实用注解,如Spring的@PostConstruct和@PreDestroy用于生命周期管理,Struts 2的@ResultType简化结果类型声明,Hibernate的@EntityListeners添加实体监听器等。这些注解...
这个框架的核心理念是通过注解(Annotations)来替代传统的XML配置,实现依赖注入、界面回调、事件处理等常见任务的自动化,从而让开发者能够更专注于业务逻辑。 在Android开发中,我们常常需要手动编写大量的初始...
Spring Actionscript 是一个针对 Actionscript3 设计的轻量级框架,其灵感来源于 Java 平台上的 Spring 框架,旨在实现控制反转(IOC)以降低组件间的耦合度。 **Spring Actionscript 框架的核心功能** 1. **IOC ...