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

《设计模式之禅》--代理扩展:动态代理

接上篇《设计模式之禅》--代理扩展:强制代理

动态代理就是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。相对来说,自己写代理类的方式就是静态代理

面向切面编程(AOP)核心就是采用了动态代理机制

public interface Subject {
    //业务操作
    public void doSomething(String str);
}
public class RealSubject implements Subject {
    //业务操作
    public void doSomething(String str) {
        System.out.println("do something!---->" + str);
    }
}
public class MyInvocationHandler implements InvocationHandler {
    //被代理的对象
    private Object target = null;

    //通过构造函数传递一个对象
    public MyInvocationHandler(Object _obj) {
        this.target = _obj;
    }

    //代理方法
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //执行被代理的方法
        return method.invoke(this.target, args);
    }
}
public class DynamicProxy<T> {
    public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {
        //寻找JoinPoint连接点,AOP框架使用元数据定义
        if (true) {
            //执行一个前置通知
            (new BeforeAdvice()).exec();
        }
        //执行目标,并返回结果
        return (T) Proxy.newProxyInstance(loader, interfaces, h);
    }
}
public interface IAdvice {
    //通知只有一个方法,执行即可
    public void exec();
}

public class BeforeAdvice implements IAdvice {
    public void exec() {
        System.out.println("我是前置通知,我被执行了!");
    }
}

调用

public class Client {
    public static void main(String[] args) {
        //定义一个主题
        Subject subject = new RealSubject();
        //定义一个Handler
        InvocationHandler handler = new MyInvocationHandler(subject);
        //定义主题的代理
        Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().
                getClassLoader(), subject.getClass().getInterfaces(), handler);
        //代理的行为
        proxy.doSomething("Finish");
    }
}

结果

我是前置通知,我被执行了!
do something!---->Finish

拓展:

public class SubjectDynamicProxy extends DynamicProxy {
    public static <T> T newProxyInstance(Subject subject) {
        //获得ClassLoader
        ClassLoader loader = subject.getClass().getClassLoader();
        //获得接口数组
        Class<?>[] classes = subject.getClass().getInterfaces();
        //获得handler
        InvocationHandler handler = new MyInvocationHandler(subject);
        return newProxyInstance(loader, classes, handler);
    }
}

 调用

public class Client {
    public static void main(String[] args) {
        //定义一个主题
        Subject subject = new RealSubject();
        //定义主题的代理
        Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);
        //代理的行为
        proxy.doSomething("Finish");
    }
}

 

相关文章:

  • IOLI-crackme0x01-0x05 writeup
  • 思考|自动化测试面试题第一波
  • 算法学习之路|欧拉回路初见
  • python3 _笨方法学Python_日记_DAY1
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 提高开发效率之VS Code基础配置篇
  • 【301】IDL与C#混合编程
  • 小总结
  • 【18】万魂杀服务器开发之SDK接入
  • 12c broker fast-start failover - ORA-16820解决
  • Nginx配置——区分PC或手机访问不同域名
  • Eclipse MicroProfile 1.3现已发布
  • VTP的模式(思科)
  • 掀开图片显示介绍的css效果
  • JS判断某变量是否为某数组中的一个值的3种方法
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • fetch 从初识到应用
  • flutter的key在widget list的作用以及必要性
  • JavaScript函数式编程(一)
  • ng6--错误信息小结(持续更新)
  • SQLServer插入数据
  • VuePress 静态网站生成
  • 不上全站https的网站你们就等着被恶心死吧
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 从零开始的无人驾驶 1
  • 构造函数(constructor)与原型链(prototype)关系
  • 前端_面试
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 移动端 h5开发相关内容总结(三)
  • 译有关态射的一切
  • 用Python写一份独特的元宵节祝福
  • ###STL(标准模板库)
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #NOIP 2014# day.2 T2 寻找道路
  • #微信小程序:微信小程序常见的配置传值
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (java)关于Thread的挂起和恢复
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (待修改)PyG安装步骤
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (附源码)计算机毕业设计大学生兼职系统
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (汇总)os模块以及shutil模块对文件的操作
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (七)Java对象在Hibernate持久化层的状态
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET 分布式技术比较
  • .netcore 获取appsettings
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .NET中的Exception处理(C#)
  • // an array of int
  • @ModelAttribute使用详解