• 代理模式(2):动态代理


    一,动态代理介绍

    • 动态代理和静态代理的角色都是一样,静态代理模式的代理类是我们提前写好的,而动态代理的类是动态生成的,其实动态代理与静态代理的本质一样,最终程序运行时都需要生成一个代理对象实例,通过它来完成相关增强以及业务逻辑,只不过静态代理需要硬编码的方式指定,而动态代理支持运行时动态生成这种实现方式。动态生成的好处很明显,在编码时,代理逻辑与业务逻辑互相独立,各不影响,没有侵入,没有耦合

    二,与动态代理相关的两个类

    •  Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现
    • Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
      Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
      Static Class getProxyClass (ClassLoader loader,Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组

    三,代码实现动态代理

    1,抽象角色

    复制代码
    1 //抽象角色
    2 public interface User {
    3 
    4     public void add();
    5 
    6 }
    复制代码

    2,真实角色

    复制代码
    1 //真实角色
    2 public class UserImpl implements User {
    3 
    4     public void add() {
    5         System.out.println("这是一个add方法");
    6     }
    7 
    8 }
    复制代码

    3,动态代理类生成的接口对象

    复制代码
     1 import java.lang.reflect.InvocationHandler;
     2 import java.lang.reflect.Method;
     3 import java.lang.reflect.Proxy;
     4 
     5 public class InvocationHandlerProxy  implements InvocationHandler {
     6 
     7     private User user;
     8 
     9     public void setUser(User user) {
    10         this.user = user;
    11     }
    12 
    13     //动态生成代理类
    14     public Object getProxy(){
    15         return Proxy.newProxyInstance(this.getClass().getClassLoader(),
    16                 user.getClass().getInterfaces(),this);
    17     }
    18 
    19     //proxy:代理类
    20     //method:代理类的调用处理程序的方法 的对象
    21     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    22         show1();
    23         Object invoke = method.invoke(user, args);
    24         show2();
    25         return invoke;
    26     }
    27 
    28     public void show1(){
    29         System.out.println("show方法1");
    30     }
    31 
    32     public void show2(){
    33         System.out.println("show方法2");
    34     }
    35 }
    复制代码

    【注意InvocationHandler导包】

     4,测试

    复制代码
     1 public class Test {
     2     public static void main(String[] args) {
     3 
     4         UserImpl userImpl = new UserImpl();
     5 
     6         InvocationHandlerProxy ihp = new InvocationHandlerProxy();
     7         ihp.setUser(userImpl);
     8 
     9         User proxy = (User) ihp.getProxy();
    10 
    11         proxy.add();
    12     }
    13 }
    复制代码

    5,运行结果

    四,总结

     动态代理的好处

    • 可以使真实角色更加纯粹,不用去关注一些公共的事情
    • 公共的业务由代理来完成,实现业务的分工
    • 公共业务的要扩展的话,可以更加集中和方便
    • 一个动态代理,一般代理一类的业务,一个动态代理可以代理多个类,代理接口
  • 相关阅读:
    SwiftyUserDefaults-封装系统本地化的框架推荐
    转:AFNetworking 与 UIKit+AFNetworking 详解
    转:KVC/KVO原理详解及编程指南
    转:NSString什么时候用copy,什么时候用strong
    代码重构原则
    转:【iOS开发每日小笔记(十一)】iOS8更新留下的“坑” NSAttributedString设置下划线 NSUnderlineStyleAttributeName 属性必须为NSNumber
    转:iOS程序main函数之前发生了什么
    转:iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
    Apple macOS Mojave Intel Graphics Driver组件任意代码执行漏洞
    巧用"记事本"让病毒无效运行
  • 原文地址:https://www.cnblogs.com/edda/p/13343864.html
Copyright © 2020-2023  润新知