• 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 动态代理原理

  • 相关阅读:
    RK3399平台开发系列讲解(FLASH篇)内核MTD层数据结构体
    常见树种(贵州省):003柏类
    ASP.NET 网页JS打印
    oracle常用命令
    洛谷C++简单题小练习day21—梦境数数小程序
    [100天算法】-二叉树剪枝(day 48)
    个人数据治理总结
    【Web3 系列开发教程——创建你的第一个 NFT(2)】NFT 历史回溯
    java-php-python-ssm文献管理平台计算机毕业设计
    用SPM技术固定EBS标准功能的SQL执行计划
  • 原文地址:https://www.cnblogs.com/SihanLin/p/17774778.html