动态代理(黑马笔记)

news2024/11/19 5:57:27

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
一、BigStar 大明星类

package com.itheima.mydynamicproxy1;
public class BigStar implements Star {
    //实现接口要重写里边的抽象方法
    private String name;
    public BigStar() {}
    public BigStar(String name) {
        this.name = name;
    }
    //唱歌
    @Override  //表示重写接口中的方法
    public String sing(String name){
        System.out.println(this.name + "正在唱" + name);
        return "谢谢";
    }
    //跳舞
    @Override
    public void dance(){
        System.out.println(this.name + "正在跳舞");
        /**
         * 在Java代码中,this关键字用于指代当前对象实例。因此this.name指的是当前BigStar类实例的name属性。
         * 当一个方法内部引用了与参数同名的成员变量时,使用this关键字可以明确地区分它们,
         * 表明你正在访问的是属于当前对象的成员变量name,而不是传递给方法的局部变量name。
         * 所以,表达式(this.name + "正在唱" + name)的意思:
         * 是将当前BigStar对象的name属性值与字符串"正在唱"以及传递给sing方法的参数name(即歌曲名)拼接起来,
         * 形成一个完整的句子,例如如果BigStar对象的name是"小明",调用sing("月亮代表我的心")时,
         * 输出将会是"小明正在唱月亮代表我的心"。
         */
    }
    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }
    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }
    public String toString() {
        return "BigStar{name = " + name + "}";
    }
}

二、Star接口,代理类和大明星类都要实现这个接口以获取代理的方法。

package com.itheima.mydynamicproxy1;
public interface Star {
    //我们可以把所有想要被代理的方法定义在接口当中
    //唱歌,因为在接口里都是抽象方法,所以方法体去掉,前面加abstra
    public abstract String sing(String name);
    //跳舞
    public abstract void dance();
}

三、 ProxyUtil 代理类

package com.itheima.mydynamicproxy1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
 * 类的作用:创建一个代理
 * */
public class ProxyUtil {
    /*
     * 方法的作用:给一个明星的对象,创建一个代理
     *  形参:被代理的明星对象
     *  返回值:给明星创建的代理

     * 在外界获取代理对象后,方法的调用是怎么样的 需求:
     *   外面的人想要大明星唱一首歌
     *   1. 获取代理的对象
     *      代理对象 = ProxyUtil.createProxy(大明星的对象);
     *   2. 再调用代理的唱歌方法
     *      代理对象.唱歌的方法("只因你太美");
     * */
    //首先要把明星的对象作为参数传过来,我才能给它创建代理
    //方法的返回值,就是我们创建的代理,
    // 所以这里类型可以写Star,因为代理ProxyUtil类 也是要实现Star这个接口的,
    // 所以在这直接写接口的类型是ok的.
    public static Star createProxy(BigStar bigStar) {
       /* java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:
      public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
        参数一:用于指定用哪个类加载器,去加载生成的代理类
        参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法,
        参数三:用来指定生成的代理对象要干什么事情*
        方法体用到了上述方法 */
        Star star = (Star) Proxy.newProxyInstance(//创建出来的是代理对象,看原方法中返回类型是Object的,但是在左边用Star来接收,所以要强转一下
                ProxyUtil.class.getClassLoader(),//参数一:用于指定用哪个类加载器,去加载生成的代理类
                // (相当于找到是谁把当前类的字节码文件加载到内存的,找到这个类加载器后,让它再去加载当前的代理到内存当中)

                new Class[]{Star.class},//参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法,
                //代码中是以数组的方式来体现的,数组中的参数都是字节码,(把接口的字节码放在数组当中)
                // new Class[]{Star.class},表示生成的代理中介,它可以代理Star这个接口里所有的方法,说白了能代理的方法都在接口当中.
                //如果接口有多个,可以把它们都写在数组当中new Class[]{Star.class,A.class,B.class}

                //参数三:用来指定生成的代理对象要干什么事情,通过实现InvocationHandler接口来实现,
                // 因为代理对象要实现Star接口,所以这里要实现InvocationHandler接口,
                //InvocationHandler是接口,因此这里要写一个InvocationHandler实现类的对象,这里用匿名内部类来做,
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /*
                         * 参数一:代理的对象
                         * 参数二:要运行的方法 sing
                         * 参数三:调用sing方法时,传递的实参,因为invoke方法就是代理要干的事情
                         */
                        if ("sing".equals(method.getName())) {
                            System.out.println("准备话筒,收钱");
                        } else if ("dance".equals(method.getName())) {
                            System.out.println("准备场地,收钱");
                        }
                        //去找大明星开始唱歌或者跳舞
                        //代码的表现形式:调用大明星里面唱歌或者跳舞的方法
                        return method.invoke(bigStar, args);//反射的反射机制,通过反射调用bigStar里面的方法,这里的args是“只因你太美”
                        //在调用方法时,如果有参数,要将参数传递过去.
                        //如果方法有返回值,可以将它的运行结果进行返回
                    }
                }
        );
        return star;//返回生成的代理
    }
}

//什么是类加载器? (就是Java在运行时,需要有一个人将那个字节码文件加载到内存中,就是类加载器去加载的)
// 类加载器:负责把一个类的字节码加载到内存中,并且生成一个Class对象.
/*
 * 1. 获取类加载器
 *   1.1 获取系统类加载器
 *       ClassLoader cl = ClassLoader.getSystemClassLoader();
 *   1.2 获取系统类加载器的父类加载器
 *       ClassLoader cl = ClassLoader.getSystemClassLoader().getParent();
 *   1.3 获取扩展类加载器
 *       ClassLoader cl = ClassLoader.getSystemClassLoader().getParent().getParent();
 *   1.4 获取应用程序类加载器
 *       ClassLoader cl = ClassLoader.getSystemClassLoader().getParent().getParent().getParent();
 */

四、测试类

package com.itheima.mydynamicproxy1;

public class Test {
    public static void main(String[] args) {
    /*
        需求:
            外面的人想要大明星唱一首歌
             1. 获取代理的对象
                代理对象 = ProxyUtil.createProxy(大明星的对象);
             2. 再调用代理的唱歌方法
                代理对象.唱歌的方法("只因你太美");
     */

        //1. 获取代理的对象 proxy
        BigStar bigStar = new BigStar("鸡哥");
        Star proxy = ProxyUtil.createProxy(bigStar);//Ctrl+alt+v  自动生成左边
        //2. 调用唱歌的方法
        String result = proxy.sing("只因你太美");
        System.out.println(result);//给谢谢返回值做打印
        //3. 调用跳舞的方法
        proxy.dance();//无参,无返回值,所以小括号里不需要带任何东西,在方法左边也不需要变量进行接收.
    }
}

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

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

相关文章

【C++课程学习】:类和对象(上)(类的基础详细讲解)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f35f;1.1类的引出&#xff1a; &#x1f35f;1.2类的结构&#xff1a; &#x1f35f;1.3类的…

代码随想录算法训练营第四十四天 | 01背包问题理论基础、01背包问题滚动数组、416. 分割等和子集

背包问题其实有很多种&#xff0c;01背包是最基础也是最经典的&#xff0c;软工计科学生一定要掌握的。 01背包问题 代码随想录 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经…

金士顿U盘被写保护的解决方法

1.适用的U盘芯片信息 USB设备ID: VID 0951 PID 1666 设备供应商: Kingston 设备名称: DataTraveler 3.0 设备修订版: 0110 产品制造商: Kingston 产品型号: DataTraveler 3.0 产品修订版: PMAP 主控厂商: Phison(群联) 主控型号: PS2251-07(PS2307) - F/W 08.03.50 [2018-…

怎么监控上网记录?监控上网记录的软件推荐

监控上网记录&#xff0c;可以防止员工摸鱼&#xff0c;许多企业为提高工作效率、保障网络安全、确保合规性而采取的措施之一。以下是几种常见的监控上网记录的方法&#xff1a; 1、安装专业电脑监控软件&#xff1a; 如“安企神”、“域智盾”、“中科安企”等&#xff0c;这…

定个小目标之每天刷LeetCode热题(10)

这道题属于一道中等题&#xff0c;看来又得背题了&#xff0c;直接看题解吧&#xff0c;有两种解法 第一种动态规划法 状态&#xff1a;dp[i][j] 表示字符串s在[i,j]区间的子串是否是一个回文串 状态转移方程&#xff1a;当s[i] s[j] && (j - i < 2 || dp[i 1]…

【数据结构】二叉树的存储结构

二叉树的存储结构 导读一、存储结构二、顺序存储结构三、链式存储结构结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在前面的内容中&#xff0c;我们已经认识了树这种新的数据结构以及二叉树这种特殊的树。 与前面我们学习的线性…

Android 调试桥_ADB命令

Android 调试桥 ADB全称 【Android Debug Bridge】 是Android SDK中的一个命令行工具&#xff0c;adb命令可以直接操作管理Android模拟器或真实的Android设备&#xff08;手机&#xff09; ADB的工作原理 启动一个 adb 客户端时&#xff0c;此客户端首先检查是否有已运行的 …

逐步掌握最佳Ai Agents框架-AutoGen 十 Web应用

AutoGen系列来到了第十篇&#xff0c;从入门AutoGen,到熟悉chat agent工作方式&#xff0c;再到深入把玩RAG文档AI助理应用。终于&#xff0c;我们要结合Streamlit来做智能Web应用了。 Streamlit Streamlit是一款Web开发框架&#xff0c;适用于python快速完成一些大模型、数学…

直播美颜工具解析:美颜SDK核心技术与性能优化方法

本篇文章&#xff0c;小编将深入解析直播美颜SDK的核心技术及其性能优化方法&#xff0c;以期为开发者提供有价值的参考。 一、美颜SDK核心技术 1.实时人脸检测与识别 美颜SDK的核心技术之一是实时人脸检测与识别。这项技术基于深度学习算法&#xff0c;能够快速、准确地识别…

实验9 静态路由配置

实验9 静态路由配置 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 网络中的每个路由器都会维护一张路由表或转发表。路由表的表项记录着目的网络信息以及下一跳I 地址。路由表可以手动配置&#xff0c;也可以通过路由算法动态生成。静态…

kali配置静态ip

kali配置静态ip 因为一些环境需要&#xff0c;本地linux主机需要搭建一个桥接模式的网络&#xff0c;那么直接就在kali中配置了&#xff0c; 打开vim /etc/network/interfaces 这里就需要自己配置一下ip&#xff0c;网关&#xff0c;路由等内容 这里参考&#xff1a;参考链接 …

C++ STL初阶(2):string 的模拟实现

此文的背景是自己实现库中的string&#xff0c;由于string的模版实现较为困难&#xff0c;我们只实现最简单char版本。 1.命名空间分割 为了避免与库中的string冲突&#xff0c;我们使用一个自己的命名空间中来分离并实现所有内容&#xff0c;并且将所有的声明和定义相分离&…

Three.js-实现加载图片并旋转

1.实现效果 2. 实现步骤 2.1创建场景 const scene new THREE.Scene(); 2.2添加相机 说明&#xff1a; fov&#xff08;视场角&#xff09;&#xff1a;视场角决定了相机的视野范围&#xff0c;即相机可以看到的角度范围。较大的视场角表示更广阔的视野&#xff0c;但可能…

P3. 创建个人中心页面

P3. 创建个人中心页面 0 概述Tips1 个人中心页面1.1 创建 Bot 表及 pojo, mapper1.2 实现 Bot 增删改查的 API1.3 实现个人中心页面前端 0 概述 主要介绍了一下添加一个表(类)&#xff0c;及其CRUD的前端和后端的实现方式&#xff0c;介绍的是通用的方法。 后端的CRUD很好写&am…

【Java面试】十五、HashMap相关

文章目录 1、二叉树1.1 二叉搜索树1.2 红黑树 2、散列表2.1 哈希冲突2.2 哈希冲突 - 链表法 3、HashMap的实现原理4、HashMap源码4.1 属性部分4.2 构造函数部分 5、HashMap的put方法的流程6、HashMap的扩容机制7、HashMap的寻址算法8、为何HashMap底层的数组长度一定是2的次幂 …

导入地址表钩取技术解析

前置知识 导入表 在一个可执行文件需要用到其余DLL文件中的函数时&#xff0c;就需要用到导入表&#xff0c;用于记录需要引用的函数。例如我们编写的可执行文件需要用到CreateProcess函数&#xff0c;就需要用到kernel32.dll文件并且将其中的CreateProcess函数的信息导入到我…

数据库管理-第198期 升级Oracle ACE Pro,新赛季继续努力(20240605)

数据库管理198期 2024-06-05 数据库管理-第198期 升级ACE Pro&#xff0c;新赛季继续努力&#xff08;20240605&#xff09;1 惊喜2 变化3 Oracle ACE总结 数据库管理-第198期 升级ACE Pro&#xff0c;新赛季继续努力&#xff08;20240605&#xff09; 作者&#xff1a;胖头鱼的…

【PCB]射频电路pcb设计

学习改变命运&#xff0c;技能成就未来&#xff01;❤~~ 1射频信号的基础知识及工作原理介绍 射频的基础知识介绍 2射频板PCB的布局要求 3射频板布局要求 4屏蔽帐设计 5射频板的层叠阻抗设计 6射频板的PCB布线原则 7射频板的PCB布线要求 8射频板的设计实战

kubeedge v1.17.0部署教程

文章目录 前言一、安装k8s平台二、部署kubeedge1.部署MetalLB(可选)2.cloud3.edge4. 部署nginx到edge端 总结参考 前言 本文主要介绍kubeedge v1.17.0的安装过程 主要环境如下表 应用版本centos7.0k8s1.28.2kubeedge1.17.0docker24.0.8centos7.0 一、安装k8s平台 本文主要参…

2024年6月1日 (周六) 叶子游戏新闻

Embracer探讨单机游戏大作涨价超过70美元的可能性在Embracer集团等待公布新公司名称的同时&#xff0c;他们对游戏大作的价格上涨做出了评论。几年来&#xff0c;游戏大作的价格已经达到了70美元的门槛。Embracer集团的CEO Lars Wingefors在采访中表示&#xff0c;电子游戏行业…