无需修改AEvent与BEvent类,如何通过通用类统一处理事件方法?
解决方案
1. 适配器模式 + 反射(简单易落地)
这种方式通过包装原有类,在不修改源码的前提下,给目标方法添加通用处理逻辑,同时保留原有功能。
首先定义通用事件处理的接口与实现:
// 通用事件处理接口 public interface EventHandler { void handleEvent(Object event); } // 通用逻辑实现类 public class CommonEventHandler implements EventHandler { @Override public void handleEvent(Object event) { // 这里编写你的统一处理逻辑 System.out.println("统一处理事件:" + event.getClass().getSimpleName()); } }
为AEvent和BEvent分别编写适配器类:
// AEvent适配器 public class AEventAdapter extends AEvent { private final EventHandler commonHandler; public AEventAdapter(EventHandler commonHandler) { this.commonHandler = commonHandler; } @Override public void onAEventCreate(A event) { // 先执行原有类的逻辑 super.onAEventCreate(event); // 触发通用处理 commonHandler.handleEvent(event); } } // BEvent适配器 public class BEventAdapter extends BEvent { private final EventHandler commonHandler; public BEventAdapter(EventHandler commonHandler) { this.commonHandler = commonHandler; } @Override public void onBEventCreate(B event) { super.onBEventCreate(event); commonHandler.handleEvent(event); } }
使用示例:
public class Main { public static void main(String[] args) { EventHandler handler = new CommonEventHandler(); AEvent aEvent = new AEventAdapter(handler); aEvent.onAEventCreate(new A()); BEvent bEvent = new BEventAdapter(handler); bEvent.onBEventCreate(new B()); } }
如果原有类的目标方法是私有,可通过反射调用:
public class AEventAdapter { private final AEvent target; private final EventHandler commonHandler; public AEventAdapter(AEvent target, EventHandler commonHandler) { this.target = target; this.commonHandler = commonHandler; } public void onAEventCreate(A event) { try { // 反射调用原有私有方法 Method method = AEvent.class.getDeclaredMethod("onAEventCreate", A.class); method.setAccessible(true); method.invoke(target, event); // 通用处理 commonHandler.handleEvent(event); } catch (Exception e) { e.printStackTrace(); } } }
2. CGLIB动态代理(无需编写多个适配器)
JDK动态代理需要接口支持,而CGLIB可以直接代理类,通过动态生成子类拦截方法调用,统一处理符合规则的方法(比如onXXCreate命名)。
先引入CGLIB依赖(Maven示例):
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
编写代理生成工具类:
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class EventProxyGenerator { private static final EventHandler COMMON_HANDLER = new CommonEventHandler(); @SuppressWarnings("unchecked") public static <T> T createProxy(Class<T> clazz) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> { // 执行原有方法逻辑 Object result = proxy.invokeSuper(obj, args); // 匹配目标方法,触发通用处理 if (method.getName().startsWith("on") && method.getName().endsWith("Create")) { if (args.length > 0) { COMMON_HANDLER.handleEvent(args[0]); } } return result; }); return (T) enhancer.create(); } }
使用示例:
public class Main { public static void main(String[] args) { AEvent aEvent = EventProxyGenerator.createProxy(AEvent.class); aEvent.onAEventCreate(new A()); BEvent bEvent = EventProxyGenerator.createProxy(BEvent.class); bEvent.onBEventCreate(new B()); } }
3. 字节码增强(ByteBuddy,适合框架级场景)
ByteBuddy是轻量易用的字节码操作库,可在类加载阶段修改字节码,注入监听逻辑,无需手动创建代理对象。
引入ByteBuddy依赖:
<dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> <version>1.14.11</version> </dependency>
编写增强逻辑:
import net.bytebuddy.ByteBuddy; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.implementation.bind.annotation.SuperCall; import java.lang.Runnable; public class EventByteBuddyEnhancer { public static void enhanceEvents() throws Exception { // 增强AEvent的onAEventCreate方法 new ByteBuddy() .subclass(AEvent.class) .method(ElementMatchers.named("onAEventCreate")) .intercept(MethodDelegation.to(CommonInterceptor.class)) .make() .load(AEvent.class.getClassLoader()) .getLoaded(); // 增强BEvent的onBEventCreate方法 new ByteBuddy() .subclass(BEvent.class) .method(ElementMatchers.named("onBEventCreate")) .intercept(MethodDelegation.to(CommonInterceptor.class)) .make() .load(BEvent.class.getClassLoader()) .getLoaded(); } } // 通用拦截器 public class CommonInterceptor { public static void intercept(@SuperCall Runnable superCall, Object event) { superCall.run(); // 执行原有方法逻辑 new CommonEventHandler().handleEvent(event); // 通用处理 } }
使用时先调用增强方法,再创建实例:
public class Main { public static void main(String[] args) throws Exception { EventByteBuddyEnhancer.enhanceEvents(); AEvent aEvent = new AEvent(); aEvent.onAEventCreate(new A()); BEvent bEvent = new BEvent(); bEvent.onBEventCreate(new B()); } }
设计模式适配
你提到的观察者模式可以结合上述方案实现:CommonEventHandler作为观察者,适配器/代理类作为被观察者的包装,当原有方法被调用时,自动通知观察者执行通用逻辑。本质上是用包装器模式扩展原有类功能,符合开闭原则。
内容的提问来源于stack exchange,提问作者Anant Majhi
相关产品推荐
相关产品推荐

