• JDK 动态代理原理


    代理模式

    客户端不直接访问目标对象,需要通过第三者来实现间接访问对象

    代理对象在客户端和目标对象之间起中介作用,能够屏蔽目标对象不想让客户端知道的内容,或增加额外的服务

    动态代理

    JDK 动态代理:基于接口,利用 JDK API 动态地在内存中构建代理对象,从而实现目标对象的代理功能。称为 JDK 代理或接口代理。

    JDK 动态代理例子

    • MapperInvocationHandler 实现 InvocationHandler 接口,实现 invoke 方法,该方法最终是代理类增强的目标类方法
    • JDKProxyFactory 用于生成代理对象的工厂,通过调用 Proxy.newProxyInstance 方法生成代理对象
    • UserMapper 目标类,JDK 代理的目标类必须实现某个接口
    • IUserMapper 目标类接口

    MapperInvocationHandler

    public class MapperInvocationHandler implements InvocationHandler {
        // 动态的目标对象
        private Object target;
    
        public MapperInvocationHandler(Object target) {
            this.target = target;
        }
        /**
         * 增强方法
         * @param proxy 代理实例
         * @param method 目标方法
         * @param args 目标方法参数
         * @return 返回值
         * @throws Throwable 异常
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("=========JDK 动态代理前置增强=========");
            method.invoke(target, args);
            System.out.println("=========JDK 动态代理后置增强=========");
            return null;
        }
    }
    

    JDKProxyFactory

    public class JDKProxyFactory {
        // 动态的目标对象
        private Object target;
    
        public JDKProxyFactory(Object target) {
            this.target = target;
        }
    
        // 为目标对象生成代理对象
        public Object getTargetProxy(){
            return Proxy.newProxyInstance(
                    // 目标对象使用的类加载器
                    target.getClass().getClassLoader(),
                    // 目标对象实现的接口
                    target.getClass().getInterfaces(),
                    // 事件处理器
                    new MapperInvocationHandler(target)
            );
        }
    }
    

    IUserMapper

    public interface IUserMapper {
        void save();
    }
    

    UserMapper

    public class UserMapper implements IUserMapper {
        @Override
        public void save() {
            System.out.println("保存用户数据");
        }
    }
    

    Client

    public class Client {
        public static void main(String[] args) {
            JDKProxyFactory jdkProxyFactory = new JDKProxyFactory(new UserMapper());
            IUserMapper userMapperProxy = (IUserMapper) jdkProxyFactory.getTargetProxy();
            userMapperProxy.save();
        }
    }
    

    运行结果

    =========JDK 动态代理前置增强=========
    保存用户数据
    =========JDK 动态代理后置增强=========
    
    Process finished with exit code 0
    

    JDK 动态代理原理

  • 相关阅读:
    uniapp微信公众号跳转到小程序(是点击微信页面上面的按钮/菜单跳转)
    Zabbix (一) --------- Zabbix 入门
    springboot基于Java Web的华家医疗器械商城设计与实现毕业设计源码261620
    量化交易之linux高级篇 - 守护进程的写法
    selenium——chromdriver版本请及时更新
    4.每天进步一点点-Python爬虫需要了解HTTP 响应报文
    数字信号处理中的 SIMD
    MacOS开发环境搭建
    Linux动态库与静态库
    自动化驱动程序管理
  • 原文地址:https://www.cnblogs.com/SihanLin/p/17774778.html