Java:SpringBoot实现JDK动态代理和CGLIB动态代理
  ndh0xMjNGcR6 2023年11月02日 26 0



目录

  • 1. JDK 动态代理
  • 2. CGLIB 动态代理
  • 总结
  • 参考文章


需要代理的对象

// 接口
public interface PayService {
    void pay();
}

// 实现
public class AliPayService implements PayService {
    @Override
    public void pay() {
        System.out.println("AliPayService");
    }
}

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;
    }
}

测试类

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
    }
}

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;
    }
}

测试类

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
    }
}

总结

实现方法

实现技术

JDK 动态代理

实现接口

CGLIB 动态代理

继承父类

参考文章

  1. 动态代理是如何实现的?
  2. JDK动态代理和CGLIB有什么区别?



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
ndh0xMjNGcR6