首页 > 其他分享 >动态代理

动态代理

时间:2023-03-24 21:35:43浏览次数:30  
标签:String 代理 sing 动态 方法 public name

动态代理思想的分析


我们想在已经可以运行的代码中添加右侧的2行代码

在种情况下如果我们直接修改,被称为侵入式修改,很可能和导致我们的所以代码都崩溃

我们又不能修改原有的代码又要插入新的功能,我们该怎么办呢?




中介怎么知道要去代理唱歌和跳舞这些方法的呢?


我们将需要代理的行为写在接口里面,代理方法和鸡哥都需要实现接口

动态代理的实现(代理实现)

对于为什么代理方和被代理方为什么都要实现接口的理解(接口里面都是被代理的行为)?

1.代理方实现了接口保证了这些行为都会被代理
2.被代理方法实现了这个接口保证了他里面一定拥有这些行为
总结:这为精准代理提供了保证

在中java专门提供了一个方法用于生成代理的对象

我们想调用代理的sing方法,在该方法的底层会自动调用invoke方法


当我们准备调用sing方法 invoke中的方法对象就是sing的对象,传入的就是sing传入的参数(鸡你太美)。并开始下面的invoke的方法题,执行sing的准备工作


接着回去找大明星唱歌,把“只因你太美”传递给大明星中的sing方法,然后sing方法开始执行

在大明星中的sing方法中将“谢谢进行返回”返回到代理类中,然后代理类进行返回,返回到测试类中

大明星类

package com.cook.trend;
//实现动态代理
//BigStar重写接口中的所有方法
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+"正在跳舞");
    }
    //
    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return "BigStar{name = " + name + "}";
    }

    public static void main(String[] args) {

    }
}

创建代理类

package com.cook.trend;

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


/*
需求:
    外面的人想要大明星唱一首歌
    1.获取代理对象
       代理对象= ProxyUtil.creatProxy(大明星的对象)
    2.再调用代理的唱歌方法
        代理对象.唱歌方法
            在调用代理的唱歌方法时,会在内部调用invoke方法进行准备工作
 */


/*
* 类的作用:
*   创建一个代理
 */
public class ProxyUtil {

    /*
    *方法的作用:
    *   给一个明星的对象,创建一个代理
    *形参:被代理的明星对象
    *返回值:给明星创建的代理
    *
     */
    public static Star createProxy(BigStar bigStar){
        /*
        java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:
        public static Object newProxyInstance (ClassLoader loader,Class<?>[]interfaces,InvocationHander h)
        参数一:用于指定哪个类加载器,去加载生成的代理类
        参数二:指定接口,这些接口用于指定生成的代理长什么样,也就是有那些方法
        参数三:用来指定生成的代理对象要干什么事情(意思就是代理需要干的准备工作)
         */
        final Star star =(Star) Proxy.newProxyInstance(
                ProxyUtil.class.getClassLoader(),//获取当前类的字节码文件然后找到加载该类的加载器(然后用这个加载器加载我们的代理类)
                new Class[]{Star.class},//将要代理行为的接口放在字节码类的对象数组中
                new InvocationHandler() {//该接口是函数式接口传入其匿名内部类
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            /*
                            *参数一:代理的对象
                            *参数二:要运行的方法 sing
                            *参数三:调用sing 方法时,传递的实参
                             */
                        //1.判断需要代理的行为并准备进行准备工作
                        if("sing".equals(method.getName())){
                            System.out.println("准备话筒,收钱");
                        }else if("dance".equals(method.getName())){
                            System.out.println("准备场地,收钱");

                        }
                            //2.去找大明星跳舞(调用大明星的跳舞的行)
                      return   method.invoke(bigStar,args);

                    }
                }
        );

        return star;
    }
}

代理接口

package com.cook.trend;
//书写想要被代理的行为
public interface Star {
    //1.唱歌
    public String sing(String name);
    //2.跳舞
    public void dance();
}

测试类

package com.cook.trend;

public class Test {
    public static void main(String[] args) {
        /*
        需求:
             外面的人想要大明星唱一首歌
             实现过程:
                1.获取代理的对象
                    代理对象 = ProUtil.crateProxy(大明星对象)
                 2.再调用代理的唱歌方法
                    代理对象.唱歌的方法("只因你太美")
         */
        //1.获取代理对象
        BigStar bigStar = new BigStar("鸡哥");
        final Star star = ProxyUtil.createProxy(bigStar);
         //2.调用代理的唱歌方法
        final String result = star.sing("只因你太美");
        System.out.println(result);
         //3.调用跳舞的方法
        star.dance();
    }
}

运行结果

标签:String,代理,sing,动态,方法,public,name
From: https://www.cnblogs.com/swtaa/p/17251201.html

相关文章

  • jdk的动态代理
    jdk动态代理:(jdk动态代理,必须有接口)1-Calculator接口内容:publicinterfaceCalculator{intadd(inti,intj);intsub(inti,intj);intmul(inti,......
  • 【LeetCode动态规划#02】图解不同路径I + II(首次涉及二维dp数组,)
    不同路径力扣题目链接(opensnewwindow)一个机器人位于一个mxn网格的左上角(起始点在下图中标记为“Start”)。机器人每次只能向下或者向右移动一步。机器人试图......
  • 代码随想录算法训练营Day52 动态规划
    代码随想录算法训练营代码随想录算法训练营Day52动态规划|300.最长递增子序列674.最长连续递增序列718.最长重复子数组300.最长递增子序列题目链接:300.最长递增子......
  • virtualbox 扩展动态磁盘 Centos7扩容
    阅读目录virtualbox扩展动态磁盘大小的坑调整VirtualBox虚拟磁盘VDI文件空间大小查看新的磁盘空间创建新分区调整LVM大小1先看一下VolumeGroup名称,我这边VGName是......
  • 动态规划
    遇到动态规划的一般解题思路:1.确定步骤状态在动态规划中的作用属于定海神针。简单来说,解动态规划的时候需要开一个数组,数组的每个元素f【i】或者f【i】【j】代表什么确定......
  • 在同一网络下手机通过代理服务连接电脑的socks
    让手机和电脑连接同一WiFi,查看电脑的IP地址。此为192.168.1.100ipconfig2.打开电脑的socks,并查看端口,此端口为108083.打开手机WIFI连接,选择高级设置,点击代理,选择......
  • ASEMI代理NXP汽车芯片MIMXRT1064CVJ5B
    编辑-ZMIMXRT1064CVJ5B工业产品交叉处理器MIMXRT1064CVJ5B是一个新的处理器系列,采用了恩智浦先进的ArmCortex®-M7内核,其运行速度高达528MHz,可提供高CPU性能和最佳实时响......
  • ASEMI代理NXP汽车芯片PCF85163T/1,518
    编辑-ZPCF85163T/1,518是一款针对低功耗进行优化的CMOS1实时时钟(RTC)和日历。还提供了可编程时钟输出、中断输出和低电压检测器。所有地址和数据通过双线双向I2C总线串行传输......
  • CAD动态块操作实例:距离乘数
    作为一名“成熟”的设计师,相信大家对于CAD动态块都不陌生,以下图为例,对部件左端进行拉伸,且拉伸后【键】仍处于部件左端的中心位置。今天,我们要用CAD动态块动作的【距离乘数......
  • Openlayers中使用Cluster实现点位元素重合时动态聚合与取消聚合
    场景Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合:Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合_BADAO_LIUMANG_QIZHI的博客-上面实现缩放地图时......