当前位置:首页 > CN2资讯 > 正文内容

CGLIB动态代理

2天前CN2资讯

1. 引入依赖  102

CGLIB既可以代理接口,又可以代理类。底层采用继承的方式实现。所以被代理的目标类不能使用final修饰。

使用CGLIB,需要引入它的依赖:

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

2. 具体实现  102

我们准备一个没有实现接口的类,如下:

package com.powernode.proxy.service; /** * 目标类 CGLIB动态代理 102 **/ public class UserService { // 目标方法 public boolean login(String username, String password){ System.out.println("系统正在验证身份..."); if ("admin".equals(username) && "123".equals(password)) { return true; } return false; } // 目标方法 public void logout(){ System.out.println("系统正在退出..."); } }

使用CGLIB在内存中为UserService类生成代理类,并创建对象:

package com.powernode.proxy.client; import com.powernode.proxy.service.TimerMethodInterceptor; import com.powernode.proxy.service.UserService; import net.sf.cglib.proxy.Enhancer; //CGLIB动态代理 102 public class Client { public static void main(String[] args) { // 创建字节码增强器对象 // 这个对象是CGLIB库当中的核心对象,就是依靠它来生成代理类。 Enhancer enhancer = new Enhancer(); // 告诉CGLIB父类是谁。告诉CGLIB目标类是谁。 enhancer.setSuperclass(UserService.class); // 设置回调(等同于JDK动态代理当中的调用处理器。InvocationHandler) // 在CGLIB当中不是InvocationHandler接口,是方法拦截器接口:MethodInterceptor enhancer.setCallback(new TimerMethodInterceptor()); // 创建代理对象 // 这一步会做两件事: // 第一件事:在内存中生成UserService类的子类,其实就是代理类的字节码。 // 第二件事:创建代理对象。 // 父类是UserService,子类这个代理类一定是UserService UserService userServiceProxy = (UserService) enhancer.create(); // 建议大家能够把CGLIB动态代理生成的代理对象的名字格式有点印象。 // 根据这个名字可以推测框架底层是否使用了CGLIB动态代理 System.out.println(userServiceProxy); // 调用代理对象的代理方法。 boolean success = userServiceProxy.login("admin", "123"); System.out.println(success ? "登录成功" : "登录失败"); userServiceProxy.logout(); } } // 底层本质 //class UserService$$EnhancerByCGLIB$$82cb55e3 extends UserService{}

和JDK动态代理原理差不多,在CGLIB中需要提供的不是InvocationHandler,而是:net.sf.cglib.proxy.MethodInterceptor

编写MethodInterceptor接口实现类:

MethodInterceptor接口中有一个方法intercept(),该方法有4个参数:

第一个参数:目标对象

第二个参数:目标方法

第三个参数:目标方法调用时的实参

第四个参数:代理方法

package com.powernode.proxy.service; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * CGLIB动态代理 102 **/ public class TimerMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object target, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { // 前面增强 long begin = System.currentTimeMillis(); // 怎么调用目标对象的目标方法呢? Object retValue = methodProxy.invokeSuper(target, objects); // 后面增强 long end = System.currentTimeMillis(); System.out.println("耗时"+(end - begin)+"毫秒"); return retValue; } }

对于高版本的JDK,如果使用CGLIB,需要在启动项中添加两个启动参数:

● --add-opens java.base/java.lang=ALL-UNNAMED

● --add-opens java.base/sun.net.util=ALL-UNNAMED

    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/24450.html

    分享给朋友:

    “CGLIB动态代理” 的相关文章

    Siteground怎么样?深入分析其安全性、正常运行时间与客户支持

    Siteground的安全性实践 谈到Siteground的安全性实践,我总是很欣赏他们的努力。作为一个成立于2004年的托管服务商,Siteground在安全方面采取了多重措施。我注意到,首先,他们为所有用户提供免费的Let’s Encrypt SSL证书。SSL证书能够加密网站与访客之间的数据,...

    如何解决甲骨文IP被墙的问题及有效方法

    谈到甲骨文,大家可能会联想到古老的文字和悠久的历史,然而随着信息技术的飞速发展,甲骨文的应用已经不仅仅局限于文化研究。在数据存储、信息管理等领域,甲骨文的IP(互联网协议)在全球范围内发挥着重要的作用。不幸的是,现如今许多用户却发现自己无法正常访问这些IP。这就是我们所说的“甲骨文IP被墙”的现象。...

    BBR脚本:提升Linux服务器网络性能的最佳选择

    BBR的基本概念 在近年来的网络技术发展中,BBR脚本不可不提。作为Google提出的拥塞控制算法,它带来了显著的性能提升。我常常会把BBR比作一位聪明的交通指挥官,它通过实时监测网络的瓶颈带宽和往返时间,像调节交通流量一样动态调整数据传输速率。这使得使用BBR的Linux服务器能够在面对不同网络条...

    Debian 修改 DNS 的详细步骤与常见问题解决方案

    在讨论 Debian 中的 DNS 修改前,我想先和大家分享一些关于 DNS 的基本信息。DNS(Domain Name System)是互联网的“电话簿”,它将我们可读的网站地址(如 www.example.com)转换为计算机能够理解的 IP 地址。这一过程对于我们浏览网页、发送邮件等操作至关重...

    Vultr注册送50美元优惠活动详细指南

    Vultr新用户注册活动概述 在寻找合适的云服务提供商时,我总是觉得选对平台会显得尤为重要。Vultr做为一个非常受欢迎的云服务提供商,给新用户带来了一项非常吸引人的优惠活动——注册即送50美元。这个活动让我感到非常兴奋,也让更多人有机会体验到高性价比的VPS服务。 这项活动非常简单易行。新用户只需...

    买域名的全流程攻略:从选择到安全管理

    购买域名是一项非常重要的投资,尤其对于那些希望在网上建立品牌或个人网站的人来说。域名不仅仅是一个网址,它是你在线身份的象征。因此,了解如何选择和购买域名显得极为关键。 选择域名时,需要考虑多个因素。首先,域名应该简洁易记,便于用户输入和分享。其次,关键字的相关性也非常重要,因为一个包含行业相关关键词...