You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:20:49