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代理[通俗易懂]

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • jar和war的区别

    jar和war的区别Jar、war在文件结构上,二者并没有什么不同,它们都采用zip或jar档案文件压缩格式。但是它们的使用目的有所区别:jar1.Jar文件(扩展名为.Jar,JavaApplicationArchive)包含Java类的普通库、资源(resources)、辅助文件(auxiliaryfiles)等。2.jar包是java打的包,一般只是包括一些编译后class文件和一些部署文件,在声…

  • javascript onpropertychange

    javascript onpropertychangeNewDocument functioninit() { all_real(); } functionall_real() { varbasePay=document.all("hrSalary.basePay").value; vartextf…

  • matlab解常微分方程组数值解法(二元常微分方程组的解法)

    上篇博客介绍了Matlab求解常微分方程组解析解的方法:博客地址微分方程组复杂时,无法求出解析解时,就需要求其数值解,这里来介绍。以下内容按照Matlab官方文档提供的方程来展开(提议多看官方文档)介绍一下核心函数ode45()一般形式:[t,y]=ode45(odefun,tspan,y0) 其中tspan=[t0tf]功能介绍:求微分方程组y′=f(t,y)从t0…

  • Android ListView默认选中某一项[通俗易懂]

    Android ListView默认选中某一项[通俗易懂]很多时候,在listview加载数据之后,我们希望默认选中第一项,然后我们在setAdapter之后写上如下代码:listview.getChildAt(0).setBackgroundResource(R.color.white);发现程序崩溃:NullPointerException,事实上,setAdapter()是异步的 ,调用了这个方法之后ListView的item并没

  • 自己整理的运维面试题,必须会。

    自己整理的运维面试题,必须会。1.mysql主从原理。**Slave开启I/O线程来请求master服务器,请求指定bin-logMaster端收到请求,Master端I/O线程响应请求通过bin-log将内容返给salveSlave将收到的内容存入relay-log中继日志中Slave端SQL实时监测relay-log日志有更新执行完毕之后,Slave端跟master端数据保持一致!**2.DNS原理。…

  • Idea激活码永久有效Idea2019.3.2激活码教程-持续更新,一步到位

    Idea激活码永久有效Idea2019.3.2激活码教程-持续更新,一步到位Idea激活码永久有效2019.3.2激活码教程-Windows版永久激活-持续更新,Idea激活码2019.3.2成功激活

发表回复

您的电子邮箱地址不会被公开。

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