JDK动态代理

news2025/1/11 17:07:57

可以针对一些不特定的类或者一些不特定的方法进行代理 可以在程序运行时动态变化代理规则
代理类在程序运行时才创建代理模式成为动态代理
代理类并不是在Java代码中定义好的 而是在程序运行时根据在Java代码中指示动态生成的

Proxy JDK动态代理 面向接口

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class Test1 {
    public static void main(String[] args) {
        Dinner dinner = new Student("张三");
        //通过动态代理获取一个代理对象 在代理对象中 对某个方法进行增强
        //ClassLoader loader 被代理的对象的类加载器
        ClassLoader classLoader = dinner.getClass().getClassLoader();
        //Class<?>[] interfaces 被代理对象所实现的所有接口
        Class[] interfaces =dinner.getClass().getInterfaces();
        //InvocationHandler h 执行处理器对象 专门用于定义增强的规则
        InvocationHandler handler = new InvocationHandler(){
            //invoke 当我们让代理对象调用任何方法时 都会触发invoke方法的执行
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //Object proxy 代理对象
                //Method method 被代理的方法
                //Object[] args 被代理方法运行时实参
                Object res = null;
                if(method.getName().equals("eat")){
                    System.out.println("饭前洗手");
                //让原有的eat方法去运行
                    res = method.invoke(dinner,args);
                    System.out.println("饭后刷碗");
                }else{
                    //如果是其他方法 正常执行
                    res = method.invoke(dinner,args);
                }
                return null;
            }
        };

        Dinner dinnerProxy = (Dinner)Proxy.newProxyInstance(classLoader,interfaces,handler);
        //dinnerProxy.eat("包子");
        dinnerProxy.eat("包子");

    }
}

interface Dinner {
    void eat(String foodName);
    void drink();
}

class Person implements Dinner{
    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public void eat(String foodName) {
        System.out.println(name + "正在吃" + foodName);
    }

    @Override
    public void drink() {

    }
}

class Student implements Dinner{
    private String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public void eat(String foodName) {
        System.out.println(name + "正在食堂吃" + foodName);
    }

    @Override
    public void drink() {
        System.out.println(name + "正在喝可乐");
    }
}

1.在不修改原有代码的 或没有办法修改原有代码的情况下
增强对象功能 使用代理对象代替原来的对象完成功能达到拓展功能的目的
2.JDK Proxy动态代理面向接口的动态代理 一定要有接口和实现类的存在
代理对象增强的是实现类 在实现接口方法重写的方法
代理对象只能增强接口中定义的的方法 类中其他和接口无关的方法无法增强
代理对象只能读取接口中方法上的注解 不能读取到实现类方法的注解

cglib 第三方动态代理 面向父类

在这里插入图片描述

import org.junit.Test;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class Test1 {
    @Test
    public void testCglib(){
        Person person = new Person();
        //获取一个Person代理对象
        //1.获取一个Enhancer对象
        Enhancer enhancer = new Enhancer();
        //2.设置父类的字节码
        enhancer.setSuperclass(person.getClass());
        //3.获取MethodIntercepter对象 用于定义增强规则
        MethodInterceptor methodInterceptor = new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                /*
                * Object o 生成以后的代理对象 personProxy
                * Method method 父类中原本要执行的方法 Person >>> eat()
                * Object[] objects 方法在调用时传入的实参数组
                * MethodProxy methodProxy 子类中重写父类的方法 personProxy >>> eat()
                */
                Object res = null;
                if (method.getName().equals("eat")){
                    //如果是eat方法 增强并运行
                    System.out.println("饭前洗手");
                    methodProxy.invokeSuper(o,objects);
                    System.out.println("饭后刷碗");
                }else{
                    //如果是其他方法 不增强运行
                    methodProxy.invokeSuper(o,objects);//子类对象方法执行 默认调用父类对应被重写的方法
                }
                return res;
            }
        };
        //4.设置回调方法
        enhancer.setCallback(methodInterceptor);
        //5.获得methodInterceptor
        Person personProxy = (Person) enhancer.create();
        //6.使用代理对象完成功能
        personProxy.eat("包子");
    }

class Person {
   private String name;

    public Person() {

    }

   public void eat(String foodName) {
      System.out.println("张三" + "正在吃" + foodName);
        }
    }
}

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

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

相关文章

前后端分离页面(从数据库到前端、后端手把手教你如何搭建 -- 功能实现:增加查询)

目录 一、准备条件 前台 后台 二、数据库设计 建议不要导入&#xff0c;导入有乱码的风险&#xff1b;新建查询运行下面代码更快捷。 三、导入前端项目 导入后使用命令行打开黑窗口&#xff0c;测试一下有没有npm -v环境 如果出现命令无效&#xff0c;就使用管理员身份打开…

SpringAOP(1)-spring源码详解(六)

上篇文章说了spring监听器&#xff0c;监听event&#xff0c;先把事件全部存储在多播器&#xff0c;通过publicEvent来触发多播器发送事件&#xff0c;他可以通过代码注解&#xff0c;或者实现接口的方式来实现事件监听&#xff0c;达到解耦和异步的效果。 Spring监听器-sprin…

Jupyter介绍和安装使用

一. 前言&#xff1a; 最近&#xff0c;小熙发现了一个有意思的工具Jupyter notebook&#xff0c;刚上手熟悉了下&#xff0c;特此记录分享。 二. 简介&#xff1a; 简单介绍并说下用途&#xff1a; Jupyter Notebook是一款开源的web应用&#xff0c;支持markdown编辑&#…

Windows为什么使用广播机制更新信息?

很多 Windows 信息通知机制是基于广播消息&#xff0c;例如&#xff0c;DDE&#xff0c;WM_FONTCHANGE 消息和系统设置的修改等。 当我们知道&#xff0c;消息的广播可能导致系统由于某个窗口停止处理消息而导致整个系统停止时&#xff0c;为什么我们还是使用广播呢&#xff1f…

【解决】VSCode编写C++自定义头文件undefined reference异常问题

最近在使用VSCode编写C程序过程中&#xff0c;自定义一个 *.h 文件&#xff0c;其中包含了函数声明&#xff0c;在主函数中引入头文件后&#xff0c;调用头文件对应C文件中的方法&#xff0c;出现了undefined reference问题&#xff0c;这个主要是配置没有正确造成的&#xff0…

Git——分支(详细解释)

目录 一、概念 1.1 服务器运行模式 1.2 分支概念 1.3 分支的好处 二、分支相关操作 2.1 分支操作 2.2 查看当前分支 2.3 创建分支 2.4 切换分支 2.4.1 切换分支 2.4.2 修改代码并提交&#xff08;完整过程&#xff09; 三、合并分支 3.1 正常合并 3.2 冲突合并&#xff…

DGL学习笔记——第一章 图

提示&#xff1a;DGL用户指南学习中 文章目录一、关于图的基本概念&#xff1f;二、图、节点和边三、节点和边的特征四、从外部源创建图1、从Scipy稀疏矩阵中构建图示例2、从networkx中构建图示例3、从csv中构建图结构总结一、关于图的基本概念&#xff1f; 图是用以表示实体及…

【推荐系统学习笔记】-- 1、推荐系统架构

根本解决的问题&#xff1a;在信息过载的情况下&#xff0c;用户如何高效获取感兴趣的信息。 1 逻辑架构 推荐系统要处理的问题就可以被形式化地定义为&#xff1a;对于某个用户U&#xff08;User&#xff09;&#xff0c;在特定场景C&#xff08;Context&#xff09;下&…

区块链 - 各个国家Web3的现状与趋势

​潜力博主推荐&#xff0c;点上面关注博主↑↑↑ 2022年&#xff0c;元宇宙、NFT 、GameFi、DAO、DeFi 等 Web3 时代的新生事物&#xff0c;正在彻底改写传统商业模式&#xff0c;重塑全球数字商业的版图&#xff0c;一个全新的数字时代正在开启。 美国、欧洲官方开始在 Web…

【构建ML驱动的应用程序】第 4 章 :获取初始数据集

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

C语言——指针初阶详解

&#x1f412;博客名&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;别人可以拷贝我的模式&#xff0c;但不能拷贝我不断往前的激情 目录 1. 指针是什么 2. 指针和指针类型 2.1指针类型的第一个意义 2.2指针类型的第二个意义 3. 野指针 3.1 野指针成因 3.2 如何…

零基础自学javase黑马课程第十六天

零基础自学javase黑马课程第十六天 ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&#x1f39e;2022年11月21日&…

三菱FX3U——ST编程点动与自锁

通过赋值 : 操作符&#xff0c;可以控制元件的状态&#xff1b; Y0:1&#xff0c;使Y0得电&#xff0c; Y0:0,使Y0失电&#xff1b; Y0:TRUE,使Y0得电&#xff0c; Y0:FALSE,使Y0失电; Y2:M0,通过M0的状态来控制Y2&#xff1b; NOT 取反操作&#xff0c; 状态取反&#xff…

活动现场大屏幕互动系统(微信墙)修复版完美PHP源码,带完整素材包和详细使用文档

源码收集于网络&#xff0c;觉得不错&#xff0c;2022-11-18亲测了源码&#xff0c;顺手修复了原来的几处bug。网上的这个源码有个重大bug&#xff0c;就是后台系统配音没法上传音乐文件。我理了一下代码&#xff0c;修复了这个问题&#xff0c;现在后台可以分别给每个模块上传…

CTFHub技能树 Web-文件上传详解

文章目录0x01 无验证0x02 前端验证0x03 .htaccess0x04 MIME绕过0x05 00截断0x06 双写后缀0x07 文件头检查0x08 其他摘抄0x01 无验证 介绍&#xff1a;直接上传后缀是php的文件即可 文件上传 <?php eval($_POST[777]);?> 进行连接 查找flag 0x02 前端验证 介…

智慧住建解决方案-最新全套文件

智慧住建解决方案-最新全套文件一、建设背景目前智慧住建的信息化现状&#xff1a;1、系统重叠建设&#xff0c;标准规范不统一2、信息应用水平不均衡&#xff0c;资源共享待提升3、应用系统众多&#xff0c;用户操作体验不佳4、原有架构难以适应“互联网”的新要求二、总体设计…

计算机中的第三个伟大发明

本节我们学习了控制计算机跳转指令的第三个发明的由来&#xff0c;以及清除指令。并且展示了计算机的整体控制部分的布线图。 第三个发明 对于跳转指令&#xff0c;有时它会跳转&#xff0c;有时不会。跳或不跳只是两种可能性&#xff0c;所以只需要一个bit就可以确定哪一种会…

【Kubernetes快速实战】

K8S官网文档&#xff1a;https://kubernetes.io/zh/docs/home/ 文章目录前言一、K8S核心特性二、K8S集群安装1.安装K8S集群1、关闭防火墙2、关闭 selinux3、关闭 swap4、给三台机器分别设置主机名5、在 k8s‐master机器添加hosts&#xff0c;执行如下命令&#xff0c;ip需要修改…

全球最受欢迎的「数字游民」城市竟然是它?

相信你已经或多或少听说过「数字游民」这个词汇了。 「数字游民」译自英文词组Digital Nomad&#xff0c;是指那些没有办公室等固定工作场所&#xff0c;利用互联网从事远程工作&#xff0c;实现地域和时间的相对自由&#xff0c;在全球范围内移动生活的人群。 想想看&#x…

STM32实战总结:HAL之电机

电机基础知识参考&#xff1a; 51单片机外设篇&#xff1a;电机_路溪非溪的博客-CSDN博客 无刷电机和有刷电机 先详细了解有刷电机&#xff1a; 带你了解&#xff08;有刷&#xff09;电机工作原理_哔哩哔哩_bilibili 再详细了解无刷电机&#xff1a; 无刷直流电机工作原理_哔哩…