博客
关于我
Spring的两种动态代理:JDK动态代理和cglib动态代理
阅读量:239 次
发布时间:2019-02-28

本文共 3559 字,大约阅读时间需要 11 分钟。

JAVA动态代理与CGLIB动态代理的对比及实现

一、原理区别

JAVA动态代理基于反射机制,通过生成实现指定接口的匿名类来实现代理。而CGLIB动态代理则是基于ASM框架,对目标类的字节码进行修改或增强,生成一个继承自目标类的子类,从而实现代理功能。

1. 接口实现的处理方式

  • JDK动态代理:默认情况下,如果目标对象实现了接口,会采用JDK动态代理实现AOP。
  • CGLIB动态代理:即使目标对象实现了接口,也可以强制使用CGLIB实现AOP。

2. 无接口对象的处理

如果目标对象没有实现任何接口,Spring会自动选择CGLIB动态代理,因为JDK动态代理无法处理无接口的目标对象。

如何强制使用CGLIB实现AOP

  • 添加CGLIB库

    • 需要添加对应的JAR文件,例如spring-boot-dependencies.properties中添加asm-5.2.0.jarcglib-3.2.5.jar等。
  • 配置Spring

    • 在Spring配置文件中添加以下配置:
  • JDK动态代理与CGLIB动态代理的区别

    1. 适用场景

    • JDK动态代理:只能针对实现了接口的类生成代理。
    • CGLIB动态代理:可以针对任意类生成代理,通常用于处理无接口的目标对象。

    2. 生成方式

    • JDK动态代理:基于反射机制,动态生成接口实现类。
    • CGLIB动态代理:基于ASM框架,静态修改目标类字节码生成子类。

    3. 优缺点

    • JDK动态代理:实现简单,性能较好。但无法代理无接口的目标对象。
    • CGLIB动态代理:实现复杂,生成子类,适合处理无接口对象,但可能导致性能损失。

    二、代码实现

    用户管理接口

    package com.lf.shejimoshi.proxy.entity;public interface UserManager {    void addUser(String userName, String password);    void delUser(String userName);}

    用户管理实现类

    package com.lf.shejimoshi.proxy.entity;public class UserManagerImpl implements UserManager {    @Override    public void addUser(String userName, String password) {        System.out.println("调用了新增的方法!");        System.out.println("传入参数为 userName: " + userName + " password: " + password);    }    @Override    public void delUser(String userName) {        System.out.println("调用了删除的方法!");        System.out.println("传入参数为 userName: " + userName);    }}

    JDK动态代理实现

    package com.lf.shejimoshi.proxy.jdk;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import com.lf.shejimoshi.proxy.entity.UserManager;import com.lf.shejimoshi.proxy.entity.UserManagerImpl;public class JdkProxy implements InvocationHandler {    private Object target;    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("JDK动态代理,监听开始!");        Object result = method.invoke(target, args);        System.out.println("JDK动态代理,监听结束!");        return result;    }    private Object getJDKProxy(Object targetObject) {        this.target = targetObject;        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);    }    public static void main(String[] args) {        JdkProxy jdkProxy = new JdkProxy();        UserManager user = (UserManager) jdkProxy.getJDKProxy(new UserManagerImpl());        user.addUser("admin", "123123");    }}

    CGLIB动态代理实现

    package com.lf.shejimoshi.proxy.cglib;import java.lang.reflect.Method;import com.lf.shejimoshi.proxy.entity.UserManager;import com.lf.shejimoshi.proxy.entity.UserManagerImpl;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CglibProxy implements MethodInterceptor {    private Object target;    @Override    public Object intercept(Object obj, Method method, Object[] arr, MethodProxy proxy) throws Throwable {        System.out.println("Cglib动态代理,监听开始!");        Object invoke = method.invoke(target, arr);        System.out.println("Cglib动态代理,监听结束!");        return invoke;    }    public Object getCglibProxy(Object objectTarget) {        this.target = objectTarget;        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(objectTarget.getClass());        enhancer.setCallback(this);        return enhancer.create();    }    public static void main(String[] args) {        CglibProxy cglib = new CglibProxy();        UserManager user = (UserManager) cglib.getCglibProxy(new UserManagerImpl());        user.delUser("admin");    }}

    运行结果

    运行以上代码,您可以在控制台中观察到JDK动态代理和CGLIB动态代理的输出结果,分别显示了两种代理方式的工作流程。

    转载地址:http://juhs.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现基于 LinkedList 的添加两个数字的解决方案算法(附完整源码)
    查看>>
    Objective-C实现基于opencv的抖动算法(附完整源码)
    查看>>
    Objective-C实现基于事件对象实现线程同步(附完整源码)
    查看>>
    Objective-C实现基于信号实现线程同步(附完整源码)
    查看>>
    Objective-C实现基于文件流拷贝文件(附完整源码)
    查看>>
    Objective-C实现基于模板的双向链表(附完整源码)
    查看>>
    Objective-C实现基于模板的顺序表(附完整源码)
    查看>>
    Objective-C实现基本二叉树算法(附完整源码)
    查看>>
    Objective-C实现堆排序(附完整源码)
    查看>>
    Objective-C实现填充环形矩阵(附完整源码)
    查看>>
    Objective-C实现声音录制播放程序(附完整源码)
    查看>>
    Objective-C实现备忘录模式(附完整源码)
    查看>>
    Objective-C实现复制粘贴文本功能(附完整源码)
    查看>>
    Objective-C实现复数类+-x%(附完整源码)
    查看>>
    Objective-C实现外观模式(附完整源码)
    查看>>
    Objective-C实现多启发式a star A*算法(附完整源码)
    查看>>
    Objective-C实现多尺度MSR算法(附完整源码)
    查看>>
    Objective-C实现多种方法求解定积分(附完整源码)
    查看>>
    Objective-C实现多组输入(附完整源码)
    查看>>
    Objective-C实现多项式函数在某个点的评估算法(附完整源码)
    查看>>