当前位置: 首页 > article >正文

Java动态代理示例代码

package proxy;

public class BigStar implements Star {

    private String name;

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

    @Override
    //明星只负责演唱,至于准备工作和扫尾工作交给代理完成
    public String sing(String singName) {
        System.out.println(this.name + "正在演唱:" + singName);
        return "演出结束,谢谢大家";
    }

    @Override
    public void dance() {
        System.out.println(this.name + "正在表演舞蹈...");
    }

    public String getName() {
        return name;
    }
}

1.Star接口

package proxy;

public class BigStar implements Star {

    private String name;

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

    @Override
    //明星只负责演唱,至于准备工作和扫尾工作交给代理完成
    public String sing(String singName) {
        System.out.println(this.name + "正在演唱:" + singName);
        return "演出结束,谢谢大家";
    }

    @Override
    public void dance() {
        System.out.println(this.name + "正在表演舞蹈...");
    }

    public String getName() {
        return name;
    }
}

明星类,实现Star接口。明星类只专注业务的实现,至于其他无关工作(如这里的准备和收尾工作)应该交给代理类完成。

package proxy;

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

public class ProxyUtil {

    //为哪个明星生成代理
    //注意,由于外部找的都是代理对象,而代理对象才去调用BigStar底层的方法。
    //因此,生成的代理对象应该和BigStar一样都有共同的方法sing和dance
    //
    public static Star createProxy(BigStar bigStar) {
        //第一个参数:用于指定一个类加载器
        //第二个参数:指定生成的代理对象应该有哪些方法,传入一个接口数组
        //第三个参数:用来指定代理对象具体应该做什么事
        Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                new Class[]{Star.class},
                new InvocationHandler() {
                    //这个invoke方法是一个回调方法
                    //当Star starProxy = ProxyUtil.createProxy(s); 创建一个代理对象时
                    //starProxy.sing("好运来") starProxy.dance() 代理对象调用sing方法或者dance方法时,
                    //这两个方法就会回调invoke方法!
                    @Override
                    //第一个参数:表示被代理的对象,也就是这里的bigStar对象
                    //第二个参数:表示回调这个invoke的方法(sing、dance)
                    //第三个参数:表示回调invoke方法中的参数(比如说sing(String sing) 中的singName)
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object o = new Object();
                        if (method.getName().equals("sing")) {
                            System.out.println("正在准备唱歌的场地和话筒...");
                            //调用被代理对象的方法
                            o = method.invoke(bigStar, args);
                            System.out.println("演唱会结束,工作人员正在清理现场...");
                        } else if (method.getName().equals("dance")) {
                            System.out.println("正在准备舞台");
                            method.invoke(bigStar, args);
                            System.out.println(bigStar.getName() + "跳舞结束,工作人员正在清理现场...");
                        }
                        return o;
                    }
                }
        );
        return star;
    }
}

代理类,注意这里采用匿名内部类的形式重写invoke方法。

package proxy;

public class Test {

    public static void main(String[] args) {

        BigStar bigStar = new BigStar("周杰伦");
        Star proxy = ProxyUtil.createProxy(bigStar);
        System.out.println(proxy.sing("双截棍"));
        proxy.dance();
    }
}

测试类


http://www.kler.cn/news/341593.html

相关文章:

  • 【PostgreSQL】提高篇——深入讨论约束(如 NOT NULL、CHECK、FOREIGN KEY)的使用及其对数据完整性的影响
  • C#-使用Serilog框架快速实现日志及其相关扩展
  • SpringBoot实现的美发门店客户关系管理(CRM)系统
  • 如何安装Llama3.1 —— 附一键安装包!
  • 【Linux探索学习】第三弹——Linux的基础指令(下)——开启新篇章的大门
  • Axios 网络请求
  • docker环境redis启动失败
  • Linux 6.11版本发布
  • 毕设 大数据抖音短视频数据分析与可视化(源码)
  • python 实现connected components连通分量算法
  • strstr
  • 【AD速成】半小时入门AltiumDesigner(速通基础)
  • 安装 Android Studio 步骤日志
  • python 进程和线程
  • RTX4060+ubuntu22.04+cuda11.8.0+cuDNN8.6.0 如何根据显卡型号和系统配置cuda和cuDNN所需的安装环境
  • go语言接口设计三国人物
  • JavaScript 第2章 基本语法
  • 华为---MUX VLAN简介及示例配置
  • 记录Android.bp里如何添加jar/aar文件
  • C++ 语言特性20 - noexcept 关键字