• Spring学习之动态代理的简单实现


    先说一下代理模式的好处

    1.可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
    2.公共的交给代理角色,实现了业务的分工
    3.公共业务发生扩展的时候,方便集中管理

    静态代理模式的缺点

    1.一个真实角色就会产生一个代理角色
    2.代码量翻倍,开发效率低

    动态代理的分类:

    1.基于接口的动态代理:JDK动态代理(本文章使用此方式)
    2.基于类的动态代理:cglib

    动态代理实现的基本条件

    需要了解JDK的两个类:

    InvocationHandler:调用处理程序

    InvocationHandler是通过一个代理实例零调用处理程序实现的接口。
    每个代理实例都有一个相关的调用处理程序。当一个方法是在一个代理实例调用,调用的方法进行编码并派遣其调用处理程序的invoke方法。

    Proxy:代理类

    Proxy创建动态代理类的实例提供了静态方法,也是所有动态代理类的父类的方法创建。

    动态代理的实现

    我们此用租房这个场景来实现动态代理

    1.首先创建租房的接口及房东实现接口的实现类

    // 租房
    public interface Rent {
        void rent();
    }
    
    // 房东
    public class landlord implements Rent {
        @Override
        public void rent() {
            System.out.println("房东要出租房子");
        }
    }
    

    2.继承InvocationHandler类,创建一个动态代理处理类

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyInvocationHandle implements InvocationHandler {
        // 被代理的接口
        private Rent rent;
    
        public void setRent(Rent rent) {
            this.rent = rent;
        }
    
        // 生成代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
        }
        // 处理代理实例,并返回处理结果
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 动态代理的本质,就是使用反射机制实现
            Object result = method.invoke(rent, args);
            return result;
        }
    }
    
    • 而getProxy()方法通过Proxy类的静态方法newProxyInstance()来生成真正的代理类
    • newProxyInstance()的第一个参数是获取类的加载器,第二个参数是被代理的接口,第三个参数是InvocationHandler接口,因为本类ProxyInvocationHandle实现了InvocationHandler接口,所以这里用this代替
    • invoke()方法通过反射机制激活被代理接口中的方法,作用是:处理代理实例,并返回处理结果

    简单来说就是:原来静态代理,一个真实角色就会需要一个代理类,重复代码多,且不灵活,现在通过JDK的InvocationHandler接口来动态的生成代理类,我们只需写一个动态代理处理类,把需要代理的对象丢进去就可以自动的生成所对应的代理类,也就是newProxyInstance()的作用。生成完代理类,需要invoke()方法来具体的处理被代理对象实例,通过method.invoke()来激活被代理对象中的方法

    3.创建实体类调用方法

    public class Client {
        public static void main(String[] args) {
            // 创建真实角色
            landlord landlord = new landlord();
            // 创建代理类处理程序
            ProxyInvocationHandle pih = new ProxyInvocationHandle();
            // 通过调用程序处理角色来处理我们的接口对象,我们把真实角色丢进去,让其代理真实角色
            pih.setRent(landlord);
            // 这里的proxy是调用程序动态生成的代理类
            Rent proxy = (Rent) pih.getProxy();
            proxy.rent();
        }
    }
    

    输出结果

    总结

    动态代理的好处就是:

    • 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
    • 公共的交给代理角色,实现了业务的分工
    • 公共业务发生扩展的时候,方便集中管理
    • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
    • 一个动态代理类可以代理多个类,只要是实现了同一接口即可

    文章引用地址:
    《狂神说JAVA之Spring动态代理》
    视频连接:https://www.bilibili.com/video/BV1WE411d7Dv?p=19

  • 相关阅读:
    REHの个人主页
    多项式基础学习笔记(2)
    多项式基础学习笔记(1)
    FFT & NTT 学习笔记
    LCT学习笔记
    莫队学习笔记
    SAM 学习笔记
    网络流学习笔记
    关于魔术球贪心做法的证明
    【题解】异或粽子&加强版
  • 原文地址:https://www.cnblogs.com/tioxy/p/13172674.html
Copyright © 2020-2023  润新知