cglib代理[通俗易懂]

cglib代理[通俗易懂]cglib代理​ 在此之前,我们学习了JDK动态代理,而JDK动态代理有一定的局限性,因为使用JDK动态代理时,被代理类必须实现接口,然后动态代理生成的代理类同时实现该接口实现代理模式,但在特定情况下没办法让被代理类实现接口,那么此时我们就需要使用cglib代理。代理模式的三要素两个成员:被代理对象、执行者(类似于Spring中切面的概念)使用场景:当某件事情不方便自己做,但是必须要做时…

大家好,又见面了,我是你们的朋友全栈君。

cglib代理

​ 在此之前,我们学习了JDK动态代理,而JDK动态代理有一定的局限性,因为使用JDK动态代理时,被代理类必须实现接口,然后动态代理生成的代理类同时实现该接口实现代理模式,但在特定情况下没办法让被代理类实现接口,那么此时我们就需要使用cglib代理。

代理模式的三要素

  • 两个成员:被代理对象、执行者(类似于Spring中切面的概念)
  • 使用场景:当某件事情不方便自己做,但是必须要做时使用代理模式。
  • 代理对象持有被代理对象的引用。

​ 在第一点中,执行者指的是代理对象的执行模板,例如在JDK动态代理中,实现InvocationHandler接口的类就是代理类中方法的执行模板。而在cglib代理中执行模板需要实现MethodInterceptor

使用cglib需要做的准备

JDK动态代理由于是JDK自带的,所以我们不需要在项目中引入第三方jar,但是cglib需要引入两个jar包:
在这里插入图片描述

cglib代理具体实例

创建被代理类

package _6代理模式.CGlib代理;

public class UserService  { 
   

    public void addUser(){ 
   
        System.out.println("添加用户");
    }

    public void deleteUser() { 
   
        System.out.println("删除用户");
    }

}

创建执行者

package _6代理模式.CGlib代理;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/** * 执行者 */
public class Executent implements MethodInterceptor { 
   
    /** * * @param o 代表代理对象本身,可以它调用代理对象的其他方法 * @param method 代理对象对应方法的字节码对象 * @param objects 传入用户调用“代理对象”对应方法的参数数组 * @param methodProxy 被代理对象方法的引用(通过它调用父类方法,从而达到代理的效果) * @return * @throws Throwable */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 
   
        System.out.println("开启事务");
        Object result= null;
        try { 
   
            result = methodProxy.invokeSuper(o,objects);
        } catch (Throwable throwable) { 
   
            throwable.printStackTrace();
            System.out.println("回滚事务");
        }
        System.out.println("提交事务");
        return result;
    }
}

通过cglib生成代理对象

public class TestCglib { 
   
    public static void main(String[] args) { 
   
       	Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(UserService.class);
        //设置执行者
        enhancer.setCallback(new Executent());
        //创建代理对象
        UserService userService = (UserService) enhancer.create();
        userService.addUser();
    }
}

执行结果:

[外链图片转存失败(img-dLKjZne6-1562928349224)(…/images/27.png)]# cglib代理

​ 在此之前,我们学习了JDK动态代理,而JDK动态代理有一定的局限性,因为使用JDK动态代理时,被代理类必须实现接口,然后动态代理生成的代理类同时实现该接口实现代理模式,但在特定情况下没办法让被代理类实现接口,那么此时我们就需要使用cglib代理。

代理模式的三要素

  • 两个成员:被代理对象、执行者(类似于Spring中切面的概念)
  • 使用场景:当某件事情不方便自己做,但是必须要做时使用代理模式。
  • 代理对象持有被代理对象的引用。

​ 在第一点中,执行者指的是代理对象的执行模板,例如在JDK动态代理中,实现InvocationHandler接口的类就是代理类中方法的执行模板。而在cglib代理中执行模板需要实现MethodInterceptor

使用cglib需要做的准备

JDK动态代理由于是JDK自带的,所以我们不需要在项目中引入第三方jar,但是cglib需要引入两个jar包:

[外链图片转存失败(img-fEj9OQOA-1562928350449)(…/images/26.png)]

cglib代理具体实例

创建被代理类

package _6代理模式.CGlib代理;

public class UserService  { 
   

    public void addUser(){ 
   
        System.out.println("添加用户");
    }

    public void deleteUser() { 
   
        System.out.println("删除用户");
    }

}

创建执行者

package _6代理模式.CGlib代理;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/** * 执行者 */
public class Executent implements MethodInterceptor { 
   
    /** * * @param o 代表代理对象本身,可以它调用代理对象的其他方法 * @param method 代理对象对应方法的字节码对象 * @param objects 传入用户调用“代理对象”对应方法的参数数组 * @param methodProxy 被代理对象方法的引用(通过它调用父类方法,从而达到代理的效果) * @return * @throws Throwable */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 
   
        System.out.println("开启事务");
        Object result= null;
        try { 
   
            result = methodProxy.invokeSuper(o,objects);
        } catch (Throwable throwable) { 
   
            throwable.printStackTrace();
            System.out.println("回滚事务");
        }
        System.out.println("提交事务");
        return result;
    }
}

通过cglib生成代理对象

public class TestCglib { 
   
    public static void main(String[] args) { 
   
       	Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(UserService.class);
        //设置执行者
        enhancer.setCallback(new Executent());
        //创建代理对象
        UserService userService = (UserService) enhancer.create();
        userService.addUser();
    }
}

执行结果:
cglib代理[通俗易懂]

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138916.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 软件工程系统设计说明书(软件详细设计说明书模板)

    1引言1.1编写目的该文档在概要设计的基础上,进一步的细化系统结构,展示了软件结构的图标,物理设计、数据结构设计、及算法设计、详细的介绍了系统各个模块是如何实现的,包括涉及到的算法,逻辑流程等。预期的读者:程序员1.2背景a. 待开发软件系统的名称:机房收费系统b. 项目的任务提出者:米新江教授c. 项目的开发者:齐智d. 项目的用户:廊坊师范学院全体在职员工及学生e. 运行该软…

    2022年4月12日
    126
  • phpstrom2021.4.2最新激活码_通用破解码

    phpstrom2021.4.2最新激活码_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月17日
    35
  • 模拟电子技术基础 思维导图

    模拟电子技术基础 思维导图模拟电子技术基础-思维导图参考孙肖子等编著.——北京:高等教育出版社,2012.12稍后将细致介绍每一章节的内容及重点应用!!!

    2022年6月20日
    40
  • SQL Server2008详细安装步骤(超详细步骤)

    SQL Server2008详细安装步骤(超详细步骤)本篇文章为安装SQLserver超详细步骤

    2022年6月23日
    26
  • IIS无法启动:发生意外错误0x8ffe2740的原因

    IIS无法启动:发生意外错误0x8ffe2740的原因原因如果系统中存在端口冲突就有可能发生本情况. IIS默认使用80端口进行HTTP通信. 如果除IIS外的应用程序正在运行并且正在相同的IP地址上使用80端口,在您试图使用IIS管理器启动网站时您也可能收到该错误讯息. 解决方法要解决这个问题,您可以进行以下任一项操作:• 在IIS管理器中更改网站绑定端口为除80端口外的其它端口. • 停止正在使用80端口的应

    2022年7月26日
    3
  • n皇后问题总结_模拟退火n皇后

    n皇后问题总结_模拟退火n皇后N皇后问题是一个经典的问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击)。一、 求解N皇后问题是算法中回溯法应用的一个经典案例      回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。     在现实中,有很多问题往往需要我们把其所有

    2022年9月30日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号