• Java:SpringBoot实现JDK动态代理和CGLIB动态代理


    需要代理的对象

    // 接口
    public interface PayService {
        void pay();
    }
    
    // 实现
    public class AliPayService implements PayService {
        @Override
        public void pay() {
            System.out.println("AliPayService");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1. JDK 动态代理

    在 JDK 动态代理中,被代理类必须实现一个或多个接口,并通过 InvocationHandler 接口来实现代理类的具体逻辑。

    实现 InvocationHandler

    package com.example.demo.proxy.handler;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class LogInvocationHandler implements InvocationHandler {
    
       private Object target;
    
        public LogInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("log before invoke");
    
            Object result = method.invoke(this.target, args);
    
            System.out.println("log after invoke");
            return result;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    测试类

    package com.example.demo.proxy;
    
    import com.example.demo.proxy.handler.LogInvocationHandler;
    import com.example.demo.proxy.impl.AliPayService;
    import org.junit.Test;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    
    public class InvocationHandlerTests {
        @Test
        public void testLogInvocationHandler() {
            PayService payService = new AliPayService();
            
            // 创建一个代理类:通过被代理类、被代理实现的接口、方法调用处理器来创建
            PayService payServiceProxy = (PayService) Proxy.newProxyInstance(
                    payService.getClass().getClassLoader(),
                    new Class[]{PayService.class},
                    new LogInvocationHandler(payService)
            );
    
            payServiceProxy.pay();
            // log before invoke
            // AliPayService
            // log after invoke
        }
    }
    
    
    • 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

    2. CGLIB 动态代理

    CGLIB 动态代理是一种使用 CGLIB 库来实现动态代理的技术。在 CGLIB 动态代理中,代理类不需要实现接口,而是通过继承被代理类来实现代理。

    package com.example.demo.proxy.handler;
    
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class LogMethodInterceptor implements MethodInterceptor {
        // 被代理对象
        private Object target;
    
        public LogMethodInterceptor(Object target) {
            this.target = target;
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("log before invoke");
    
            Object result = method.invoke(this.target, args);
    
            System.out.println("log after invoke");
            return result;
        }
    }
    
    
    • 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

    测试类

    package com.example.demo.proxy;
    
    import com.example.demo.proxy.handler.LogMethodInterceptor;
    import com.example.demo.proxy.impl.AliPayService;
    import org.junit.Test;
    import org.springframework.cglib.proxy.Enhancer;
    
    public class LogMethodInterceptorTests {
    
        @Test
        public void testLogMethodInterceptor() {
            PayService target = new AliPayService();
    
            PayService proxy = (PayService) Enhancer.create(
                    target.getClass(),
                    new LogMethodInterceptor(target)
            );
    
            proxy.pay();
            // log before invoke
            // AliPayService
            // log after invoke
        }
    }
    
    
    • 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

    总结

    实现方法实现技术
    JDK 动态代理实现接口
    CGLIB 动态代理继承父类

    参考文章

    1. 动态代理是如何实现的?
    2. JDK动态代理和CGLIB有什么区别?
  • 相关阅读:
    iSlide2024一款基于PPT的插件工具包含38个设计辅助功能
    网络中的一些基本概念
    一个基于C#开发的Excel转Json工具
    基于JAVA模拟考试系统计算机毕业设计源码+数据库+lw文档+系统+部署
    使用 JMeter 和 Docker 进行服务存根
    【故障公告】数据库服务器今年第七次 CPU 100% 故障(12月8日又出现)
    AJAX——AJAX的异步与同步、AJAX代码封装
    Mysql-体系结构
    2022微服务面试题 最新50道题(含答案解析)
    18_ue4捡钥匙进房间
  • 原文地址:https://blog.csdn.net/mouday/article/details/133942511