根据Feign的原理之定义JDK接口代理功能

使用背景

有时候我的某些接口去完成一些特定的功能时,我们可以把功能抽离出来用代理的方式去实现,只需要定义接口不需要实现类,用代码的方式去生成所谓的实现方法(其实是没有实现法方的,只是变相调用指定的功能,而CGLIB不是这样的)feign的实现过程就是这样的。

代码实现

定义方法代理的接口,用于实现代理方法具体要实现的内容

/**
 * @Description 定义方法代理的接口
 * @Date 2023-04-13 9:24
 * @Author zhangkaiqiang
 **/
public interface MethodHandler {
    Object invoke(Object[] argv) throws Throwable;
}

代理方法的实现类,实现该方法具体要干什么事,返回什么结果

 /**
  * @Description 代理方法的实现类
  * @Date 2023-04-13 9:45
  * @Author zhangkaiqiang
  **/
 public class ZkqMethodHandler implements MethodHandler{

     private Method method;

     public ZkqMethodHandler(Method method) {
         this.method = method;
     }
     
     // 具体代理的内容可以在这里实现
     @Override
     public Object invoke(Object[] argv) throws Throwable {
         System.err.println("代理方法实现类:"+ method.getName());
         return method.getName();
     }
 }

实现JKD动态代理接口,根据JDK的动态方法名去动态调用对应的实现该方法的类的实例

/**
 * @Description 实现JKD动态代理接口
 * @Date 2023-04-13 9:05
 * @Author zhangkaiqiang
 **/
public class ZkqInvocationHandler implements InvocationHandler {
    private final Map<Method, MethodHandler> dispatch;
    public ZkqInvocationHandler(Map<Method, MethodHandler> dispatch) {
        this.dispatch = dispatch;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 这个是JDK的接口代理
        System.err.println("当前执行的方法名是:"+ method.getName());
        // method这个method是接口的method, 我们要调用实现先类的method
        return dispatch.get(method).invoke(args);
    }
}

反射生产代理类,根据传进来的Class对象动态生成所有方法的实例对象

/**
 * @Description 反射生产代理类
 * @Date 2023-04-13 9:08
 * @Author zhangkaiqiang
 **/
public class ReflectiveZkq {

    public static <T> T newInstance(Class<T> target) {
        Method[] methods = target.getMethods();
        Map<Method, MethodHandler> map = new HashMap<Method, MethodHandler>();
        for (Method method: methods) {
            // 反射生产代理方法这个是接口代理,JDK只支持接口代理,不支持类代理
            map.put(method, new MethodHandler.ZkqMethodHandler(method));
        }
        ZkqInvocationHandler handler = new ZkqInvocationHandler(map);
        T proxy = (T) Proxy.newProxyInstance(target.getClassLoader(), new Class<?>[]{target}, handler);
        return proxy;
    }
}

测试JDK接口动态代理

使用main可以直接生成和调用我们写的代理对象

public class DemoApplication {
    public static void main(String[] args) throws IOException {
        ZkqInterface zkqInterface = ReflectiveZkq.newInstance(ZkqInterface.class);
        System.err.println("代理方法返回的结果" + zkqInterface.zkqMethod());
    }
}

测试结果

当前执行的方法名是:zkqMethod
代理方法实现类:zkqMethod
代理方法返回的结果zkqMethod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值