• 代理模式——静态代理和动态代理


    1. 代理模式

        代理模式是一种比较好的理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

        代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。

    2. 静态代理

    2.1 静态代理描述

        静态代理中,我们对目标对象的每个方法的增强都是手动完成的(后面会具体演示代码),非常不灵活(比如接口一旦新增加方法,目标对象和代理对象都要进行修改)且麻烦(需要对每个目标类都单独写一个代理类)。从 JVM 层面来说, 静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的 class 文件。

    2.2 静态代理实现步骤

    • 定义一个接口及其实现类;
    • 创建一个代理类同样实现这个接口
    • 将目标对象注注入进代理类,然后在代理类的对应方法调用目标类中的对应方法。这样的话,我们就可以通过代理类屏蔽对目标对象的访问,并且可以在目标方法执行前后做一些自己想做的事情。

    2.3 静态代理举例

    • 静态代理实现图书购买的业务,定义接口,目标对象和实现类,在静态代理中,目标对象和代理类都实现了接口,代理类在实现目标对象的功能基础上增加了业务
      在这里插入图片描述

    3. 动态代理

    3.1 动态代理描述

    • 相比于静态代理来说,动态代理更加灵活。我们不需要针对每个目标类都单独创建一个代理类,并且也不需要我们必须实现接口,我们可以直接代理实现类( CGLIB 动态代理机制)。

    • 从 JVM 角度来说,动态代理是在运行时动态生成类字节码,并加载到 JVM 中的。

    3.2 JDK动态代理实现

        在 Java 动态代理机制中 InvocationHandler接口和 Proxy 类是核心。

    理解

        JDK动态代理:相较于静态代理最大的区别就是动态代理中的业务实现是动态的,拓展业务功能也是动态的(例如可以实现事务,也可以输出日志…),在静态中拓展业务是规定好了的

    Proxy 类中使用频率最高的方法是:

    • newProxyInstance() ,这个方法主要用来生成一个代理对象
      • loader :类加载器,用于加载代理对象。
      • interfaces : 被代理类实现的一些接口;
      • new InvocationHandler() : 实现了 InvocationHandler 接口的对象;

        要实现动态代理的话,还必须需要实现InvocationHandler 来自定义处理逻辑。当我们的动态代理对象调用一个方法时候,这个方法的调用就会被转发到实现InvocationHandler 接口类的 invoke 方法来调用

    • invoke() 方法有下面三个参数:
      • proxy :动态生成的代理类
      • method : 与代理类对象调用的方法相对应
      • args : 当前 method 方法的参数。

    实现举例:
    在这里插入图片描述

    Service接口

    public interface Service {
    
        //实现图书购买业务
        void buy();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    BookServiceImpl实现类

    public class BookServiceImpl implements Service {
    
        //此类是目标对象
        public void buy(){
            System.out.println("图书购买业务功能实现......");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ProductServiceImpl实现类

    public class ProductServiceImpl implements Service {
        @Override
        public void buy() {
            System.out.println("商品购买功能实现......");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    代理工厂

    public class ProxyFactory {
    
        //创建动态代理对象
        public static Object getProxy(Service target){
            return Proxy.newProxyInstance(
                    //类加载器
                    target.getClass().getClassLoader(),
                    //目标对象实现的所有接口
                    target.getClass().getInterfaces(),
                    //代理功能的实现
                    new InvocationHandler() {
                        @Override
                        public Object invoke(
                                //代理对象
                                Object proxy,
                                //正在被调用的方法
                                Method method,
                                //目标对象的参数
                                Object[] args) throws Throwable {
                            	System.out.println("业务功能拓展1......");
                                //业务功能实现
                              Object  obj = method.invoke(target, args);
                                System.out.println("业务功能拓展2......");
                               return obj;
                        }
                    }
            );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    测试类:
    在测试中想实现那个功能就向代理工厂中传入对应的实现类对象即可

    @Test
        public void testProxyFactory(){
            Service obj = (Service) ProxyFactory.getProxy(new BookServiceImpl());
            obj.buy();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    系统打印服务已关闭,竟然是它的问题!
    chrome盗取用户身份
    计算机领域期刊会议级别分类
    异常:java lang AbstractMethodError
    debian安装portainer
    深度学习·理论篇(2023版)·第004篇深度学习和概率论基础01:使用大白话举例说明条件概率独立概率+期望值方差+协方差+熵和平均编码长度的关系
    ASP.NET基于WEB的选课系统
    Redis实现消息队列
    一体化运维监控:数据中心运维可视化的指挥中枢
    [Latex]公式编辑,编号、对齐【持】
  • 原文地址:https://blog.csdn.net/weixin_44606952/article/details/126654712