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

如何让JDK动态代理仅代理接口中的单个指定方法?

解决方案

JDK动态代理的InvocationHandler#invoke方法默认会接收该接口所有方法的调用请求,只需在方法内部增加匹配规则,仅对doSomething方法执行代理增强逻辑,其余方法直接转发到原对象执行即可。

实现方式1:方法名字符串匹配(简单直观)

直接判断当前调用方法的名称是否为doSomething,匹配成功才执行增强逻辑:

class DynamicProxy implements InvocationHandler{
    private Action work;
    public DynamicProxy(Action action){
        this.work = action;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 仅对doSomething方法做增强处理
        if ("doSomething".equals(method.getName())) {
            System.out.println(method.getName()+" start");
            Object result = method.invoke(work,args);
            System.out.println(method.getName()+" end");
            return result;
        }
        // 其他方法直接调用原对象的对应方法,不做增强
        return method.invoke(work,args);
    }
}

代理对象生成逻辑不需要修改,和原有逻辑保持一致即可。

实现方式2:Method对象匹配(更安全)

预先获取目标方法的实例做比对,避免字符串拼写错误导致匹配失效的问题:

class DynamicProxy implements InvocationHandler{
    private Action work;
    // 预先定义需要代理的方法实例
    private final Method targetMethod;

    public DynamicProxy(Action action) throws NoSuchMethodException {
        this.work = action;
        this.targetMethod = Action.class.getMethod("doSomething");
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 比对方法对象,匹配成功才执行增强
        if (method.equals(targetMethod)) {
            System.out.println(method.getName()+" start");
            Object result = method.invoke(work,args);
            System.out.println(method.getName()+" end");
            return result;
        }
        return method.invoke(work,args);
    }
}

两种实现效果一致:调用action.doSomething()时会输出前后增强日志,调用action.dontProxy()时不会执行任何代理逻辑,直接返回原方法执行结果。

内容的提问来源于stack exchange,提问作者Adolphus Holmes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:36:05