使用泛型简化动态代理

说明##

  1. 本文适合对动态代理有最最基本了解的人,可参看AOP的底层实现-CGLIB动态代理和JDK动态代理
  2. 本文目的在于简化动态代理的调用

maven依赖##

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.5</version>
    </dependency>

类图##

代码##

Shape###

public interface Shape {
    void draw();
}

Circle###

public class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println("我是一个圆~");
    }
}

Square###

public class Square implements Shape{
    @Override
    public void draw() {
        System.out.println("我是一个四方形~");
    }
}

DynamicProxy###

public interface DynamicProxy<T> {
    T bind();
}

JDKDynamicProxy###

public class JDKDynamicProxy<T> implements DynamicProxy<T>, InvocationHandler {
    public JDKDynamicProxy(T t) {
        this.t = t;
    }

    private T t;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("method " + method.getName() + " begin");
        method.invoke(t, args);
        System.out.println("method " + method.getName() + " end");
        return null;
    }

    @Override
    public T bind() {
        return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), this);
    }
}

CGLibDynamicProxy###

public class CGLibDynamicProxy<T> implements DynamicProxy<T>, MethodInterceptor {
    private T t;

    public CGLibDynamicProxy(T t) {
        this.t = t;
    }

    public T bind() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(t.getClass());
        enhancer.setCallback(this);
        T t = (T) enhancer.create();
        return t;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("method " + method.getName() + " begin");
//        methodProxy.invokeSuper(o, objects);
        method.invoke(t,objects);
        System.out.println("method " + method.getName() + " end");
        return null;
    }
}

Demo###

public class Demo {
    public static void main(String[] args) {

        Shape shape = new Circle();
        CGLibDynamicProxy<Shape> cgLibDynamicProxy = new CGLibDynamicProxy<>(shape);
        cgLibDynamicProxy.bind().draw();

        shape = new Square();
        JDKDynamicProxy<Shape> jdkDynamicProxy = new JDKDynamicProxy<>(shape);
        jdkDynamicProxy.bind().draw();
    }
}

运行结果##

注意##

cglib中使用methodProxy和method可以达到同样的效果,但是所调参数不一样,否则会报错,具体原因无意深究,会用即可。

posted @   舒山  阅读(1454)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
历史上的今天:
2016-09-08 闪回技术、 视图, 同义词
点击右上角即可分享
微信分享提示