代码生活处处是代理--静态代理+动态代理的实现

news2025/1/23 21:18:33
你买房了吗?你买车了吗?你买啥啥啥了吗?现在这个社会除了物理物质我们离不开,还有一种角色也在潜移默化中渗透我们的生活。---中介
代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。
接下来我们看看如何通过java来实现代理功能。

jdk动态代理

  • jdk动态代理是Java提供的一种方式,最大的特点是保留了静态代理的风格。jdk动态代理只能代理接口。这也是他和cglib的区别,也是他的缺点。jdk动态代理通过Proxy进行创建代理对象的。通过java.lang.reflect.InvocationHandler接口控制方法代理拦截的。
  • 接口类
public interface Developer {

    /**
     * 编码
     */
    void code();

    /**
     * 解决问题
     */
    void debug();
}
  • 真实类
public class JavaDeveloper implements Developer {
    @Override
    public void code() {
        System.out.println("java code");
    }

    @Override
    public void debug() {
        System.out.println("java debug");
    }
}
  • 代理类
public class JavaDynamicProxy {
    public static void main(String[] args) {
        JavaDeveloper jDeveloper = new JavaDeveloper();
        Developer developer = (Developer) Proxy.newProxyInstance(jDeveloper.getClass().getClassLoader(), jDeveloper.getClass().getInterfaces(), (proxy, method, params) -> {
            if (method.getName().equals("code")) {
                System.out.println("我是一个特殊的人,code之前先分析问题");
                return method.invoke(jDeveloper, params);
            }
            if (method.getName().equals("debug")) {
                System.out.println("我没有bug");

            }
            return null;
        });
        developer.code();
        developer.debug();
    }
}
  • 效果

  • 解析
  • 首先定义一个接口包含code、bug方法。
  • 然后我们定义一个实现类是Java程序员的工作,对应的功能是java code 、 java bug
  • 然后我们不需要提供代理类,这里通过Proxy进行创建代理对象。但是我们需要一个方法拦截器。这个拦截器在Proxy.newProxyInstance方法中传入。这个方法有三个参数:
    • classLoader : 类加载器(通过接口获取)
    • interface : 接口
    • 拦截器 : 需要我们继承InvocationHandler , 上述代码直接通过lombad表达式书写的。
  • 我们可以看到在拦截器里我们就可以控制方法转发前后的节点了。

cglib动态代理

  • 有了jdk动态代理我们开发代理就很方便了。这个时候还有一个问题。我们平时开发中不可能每个类都有继承接口的。这个时候我们的普通类如果想实现代理改如何实现呢。我们看看spring中aop的类也是没有实现接口的。这个是如何实现的呢。下面我们用cglib告诉你
  • 接口
public class HelloService {
    public HelloService() {
        System.out.println("HelloService构造");
    }

    final public String sayHello(String name) {
        System.out.println("HelloService:sayOthers>>"+name);
        return null;
    }

    public void sayHello() {
        System.out.println("HelloService:sayHello");
    }
}
  • 拦截器
public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("======插入前置通知======");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("======插入后者通知======");
        return object;
    }
}
  • Test
public static void main(String[] args) {
    //代理类class文件存入本地磁盘方便我们反编译查看源代码
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/root/code");
    //通过CGLIB动态代理获取代理对象过程
    Enhancer enhancer = new Enhancer();
    //设置enhancer对象的父类
    enhancer.setSuperclass(HelloService.class);
    // 设置enhancer的回调对象
    enhancer.setCallback(new MyMethodInterceptor());
    //创建代理对象
    HelloService helloService = (HelloService) enhancer.create();
    //通过代理对象调用目标方法
    helloService.sayHello();
}
  • cglib可以代理任何类。这是他的优点。他的创键也很简单。通过Enhancer将类与拦截器进行关联,我们的拦截器是实现net.sf.cglib.proxy.MethodInterceptor的。在intercept方法中我们可以通过methodProxy.invokeSuper进行转发方法。在转发前我们可以进行节点的控制。
    • object : 表示增强的对象,具体的实现类
    • method : 表示被拦截的方法
    • args : 参数
    • methodProxy : 父类的方法对象。 这里值得注意的是我们要通过methodProxy.invokeSuper.如果换成method调用将会一直递归拦截造成内存溢出。

总结

代理类对于我们使用这来说是无感知的。因为他和委托类继承同一个接口,所以我们在调用的时候方法都是一样的。只不过在代理类内部会在转发到委托类之前和之后进行相应的处理。代理分为静态代理和动态代理。而动态代理我们常见的有jdk动态代理、cglib动态代理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1045915.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习实验】卷积神经网络(四):自定义二维汇聚层:最大汇聚(max pooling)和平均汇聚(average pooling)

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. Conv2D(二维卷积层) 2. Pool2D(二维汇聚层) 理论知识 a. 初始化 b. 前向传播(最大汇聚层) c. 前向传播(平均汇聚…

GLTF编辑器也可以转换GLB模型

1、GLB模型介绍 GLB(GLTF Binary)是一种用于表示三维模型和场景的文件格式。GLTF是"GL Transmission Format"的缩写,是一种开放的、跨平台的标准,旨在在各种3D图形应用程序和引擎之间进行交换和共享。 GLB文件是GLTF文件…

ubuntu22.04怎么安装微信3.2.1

下载微信和wine的安装包 https://archive.ubuntukylin.com/software/pool/partner/ 使用root权限安装wine apt-get install -f -y ./ukylin-wine_70.6.3.25_amd64.deb安装微信 apt-get install -f -y ./ukylin-wechat_3.0.0_amd64.deb安装成功会出来一个页面

高仿互站网站源码 后台手机端两套模板 电脑端二十套模版

高仿互站网 后台手机端两套模板 电脑端二十套模版,简单介绍几个功能, 支持用户注册开店 开店申请,支持用户发布自己商品 支持卡密形式或实物形式, 支持用户自己发布求助 任务大厅功能,源码完整 更多功能自己去发现吧…

低代码平台如何助力国内企业数字化转型?

数字化是什么 数字化(Digitalization)是将许多复杂多变的信息转变为可以度量的数字、数据,再以这些数字、数据建立起适当的数字化模型,把它们转变为一系列二进制代码,引入计算机内部,进行统一处理&#xf…

【Linux】生产者和消费者模型

生产者和消费者概念基于BlockingQueue的生产者消费者模型全部代码 生产者和消费者概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。 生产者和消费者彼此之间不直接通讯,而通过这个容器来通讯,所以生产者生产完数据之后不用等待…

网安工具 | Windows便携式渗透测试环境PentestBox入门到进阶使用指南

微信改版了,现在看到我们全凭缘分,为了不错过【全栈工程师修炼指南】重要内容及福利,大家记得按照上方步骤设置「接收文章推送」哦~ 关注【公众号】回复【学习交流群】加入【SecDevOps】学习交流群! 文章目录: 本文为作者原创文章…

Kafka Log存储解析以及索引机制

1.概述 在Kafka架构,不管是生产者Producer还是消费者Consumer面向的都是Topic。Topic是逻辑上的概念,而Partition是物理上的概念。每个Partition逻辑上对应一个log文件,该log文件存储是Producer生产的数据。Producer生产的数据被不断追加到该…

CSP-J第二轮试题-2021/2/3年-注意事项

参考: https://blog.csdn.net/Keven_11/article/details/126388791 https://www.cnblogs.com/-Wallace-/p/cpp-stl.html 2021年真题要求 2022年真题要求 考试注意事项 优先注意&#xff1a; 1.使用freopen。 #include <bits/stdc.h> #include<cstdio>//必须包含…

晨控CK-FR08系列读写器与LS可编程逻辑控制器MODBUSRTU连接手册

晨控CK-FR08系列读写器与LS可编程逻辑控制器MODBUSRTU连接手册 晨控CK-FR08是一款基于射频识别技术的高频RFID标签读卡器&#xff0c;读卡器工作频率为13.56MHZ&#xff0c;支持对I-CODE 2、I-CODE SLI等符合ISO15693国际标准协议格式标签的读取。读卡器内部集成了射频部分通信…

spring-boot入门之如何利用idea创建一个spring-boot项目

1.创建流程&#xff01;&#xff01;&#xff01; 选择新建项目&#xff0c;这里我们需要注意是基于maven建立的和java版本和jdk版本要对应 这里我们是基于web项目创建的记得选择这个框架。 2.测试程序 编写hello测试类 我们需要通过程序的入口进行启动程序。idea已经为我们自…

【算法练习Day7】反转字符串替换空格反转字符串中的单词左旋转字符串

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 反转字符串反转字符串 I…

【洛谷 P1644】跳马问题 题解(深度优先搜索)

跳马问题 题目背景 在爱与愁的故事第一弹第三章出来前先练练四道基本的回溯/搜索题吧…… 题目描述 中国象棋半张棋盘如图 1 1 1 所示。马自左下角 ( 0 , 0 ) (0,0) (0,0) 向右上角 ( m , n ) (m,n) (m,n) 跳。规定只能往右跳&#xff0c;不准往左跳。比如图 1 1 1 中所…

修改switch Nand无线区码 以支持高频5G 信道

环境&#xff1a;NS switch 问题&#xff1a;日版&#xff0c;港版无法连接大于44信道的5G WIFI 解决办法&#xff1a;修改PRODINFO.dec的WIFI 区域码 背景&#xff1a;我的switch是最早买的港版的一批&#xff0c;WIFI 只能连接日本的信道&#xff0c;家里的路由器是大陆的&am…

CentOS7安装Oracle XE记录

本文仅是CentOS7安装Oracle XE记录&#xff0c;供参考 1、下载安装包 oracle-xe-11.2.0-1.0.x86_64.rpm.zip 2、安装 &#xff08;1&#xff09;第一次安装 [rootnode1 opt]# cd oracle-xe/ [rootnode1 oracle-xe]# ll 总用量 309884 -rw-r--r-- 1 root root 317320273 6月…

软件设计模式系列之十七——解释器模式

1 模式的定义 解释器模式是一种行为型设计模式&#xff0c;它用于将一种语言或表达式解释为对象。该模式通过定义语言的文法规则&#xff0c;并使用解释器来解释和执行这些规则&#xff0c;将复杂的语言转换为对象的操作。 在软件开发中&#xff0c;解释器模式常用于处理类似…

初识ebpf

介绍eBPF技术 当代计算机系统中&#xff0c;性能、安全性和可观察性是至关重要的关键因素。为了应对这些挑战&#xff0c;Linux 内核引入了一种名为eBPF&#xff08;extended Berkeley Packet Filter&#xff09;的强大技术。eBPF 不仅仅是一种网络数据包过滤器&#xff0c;它…

轻松拿下Offer!20个Salesforce管理员顾问的基础面试问题

先是Salesforce第二财季业绩远超预期&#xff0c;股价大涨&#xff0c;后是首席执行官Marc Benioff表示将在各部门招聘3300名员工&#xff0c;生态系统呈现欣欣向荣的态势&#xff0c;Salesforce也成为越来越多人的职业选择。 管理员作为入门级的岗位&#xff0c;是小白和新手…

黑豹程序员-再不怕猪队友把配置文件上传git暴露数据库密码了

问题&#xff1a; 项目中含有配置文件&#xff0c;而配置文件中含有数据库的用户名和密码。而团队猪队友不论三七二十一玩git时全都上传git。git上开放给外部用户。外部用户获得数据库ip地址&#xff0c;用户名&#xff0c;密码。如果运维猪队友数据库为方便直接对外网开放。那…

CSS笔记——Display属性元素分类(行内、块,行内块)CSS默认样式及解决方案

1、display属性 ​ 可取值&#xff1a; ​ none 影藏&#xff08; 自身及其后代&#xff0c;一般用block值恢复&#xff09; ​ block 块元素 ​ inline 行内元素 ​ inline-block 行内块元素 ​ list-item (l列表元素的display值&#xff0c;实际效果比块元素多了列表的项目符…