java动态代理和CGLIB

参考:https://www.jianshu.com/p/cbd4c1ad8a75

上一篇我们利用jdk的动态代理实现了一个简单的注解处理器,可以自动给一个button添加指定的监听器.

但是jdk的动态代理有一个不足之处,就是他代理的类必须实现了一个接口,如果我们要代理的类就是一个类,没有实现接口,

那么jdk的动态代理就无能无力了,这个时候我们需要用到一个更为强大的工具cglib,他可以动态给要代理的类生成一个子类

由子类代替父类完成工作,并作一定的功能增强.

下面我们举一个简单的例子,我又一个类,他只负责打招呼

public class Hello {

    public void sayHello(){
        System.out.println("hello,world");
    }
}

现在我在不改变这个类的基础上,想对他进行功能增强,应该怎么办?

肯定是使用代理啊,那Hello是个类,没有实现接口,我们只能用cglib,cglib是一个第三方的库,我们要先引进来

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

 

接下来我们要定义一个方法过滤器,对sayHello进行增强,其中

methodProxy.invokeSuper(obj, args);就是调用原来hello里的sayHello
复制代码
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class HelloMethodInterceptor implements MethodInterceptor {
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("log before method");
        Object result = methodProxy.invokeSuper(obj, args);
        System.out.println("log after method");
        return result;
    }
}
复制代码

然后我们写一个例子,测试下效果

复制代码
import net.sf.cglib.proxy.Enhancer;

public class HelloProxy {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Hello.class);
        enhancer.setCallback(new HelloMethodInterceptor());
        Hello proxy =(Hello) enhancer.create();
        proxy.sayHello();
    }
}
复制代码

输出

log before method
hello,world
log after method

事实证明,cglib已经完美实现了我们想要的功能.

对比jdk的动态代理可以发现:

cglib的MethodInterceptor就相当于jdk动态代理中的InvocationHandler

cglib中的Enhancer就相当jdk动态代理中的Proxy

用法基本相同,只不过jdk动态代理基于接口实现,cglib是基于子类继承父类.

//代理的静态实现,更像Proxy.newInstance
        Hello proxy2 =(Hello) Enhancer.create(Hello.class, new HelloMethodInterceptor());
        proxy2.sayHello();

 当然我们可以对上面的类进行改造,把方法过滤器和代理类的实现放在一个类中

复制代码
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 HelloMethodInterceptor implements MethodInterceptor {
    private Object obj;

    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("log before method");
        Object result = methodProxy.invokeSuper(obj, args);
        System.out.println("log after method");
        return result;
    }


    public Object createProxy(Object obj){
        this.obj=obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.obj.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
}
复制代码

测试一下效果

public class HelloProxy {
    public static void main(String[] args) {
        HelloMethodInterceptor interceptor = new HelloMethodInterceptor();
        Hello proxy = (Hello) interceptor.createProxy(new Hello());
        proxy.sayHello();
    }
}

代码更加简洁,功能还是一样

posted @   Mars.wang  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
历史上的今天:
2021-03-12 计算机系统、文化、概论、导论类经典PDF电子书合集
2021-03-12 大数据hadoop,spark,flink等经典电子书PDF下载
点击右上角即可分享
微信分享提示