Java动态代理

62 阅读1分钟

区别

  • 实现方式
  1. JDK动态代理是基于接口(要求代理类必须实现接口)
  2. CGlib是基于类去实现的(不能代理final类 和 final 方法)
  • 实现机制
  1. JDK动态代理是使用反射机制
  2. CGLIB是基于字节码操作

实例代码

  • JDK动态代理
package com.it.zy.proxy.DynamicProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* @author zy
* @version 1.0
* @description : JDK动态代理
* @date 2024/12/1 15:53
*/
interface MyService {
    void serve();
}

class MyServiceImpl implements MyService {
    public void serve() {
        System.out.println("Serving...");
    }
}

class MyInvocationHandler implements InvocationHandler {
    private final Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method: " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("After method: " + method.getName());
        return result;
    }

}

public class JDKProxy {
    public static void main(String[] args) {
        MyServiceImpl myService = new MyServiceImpl();
        MyService proxy = (MyService) Proxy.newProxyInstance(myService.getClass().getClassLoader(), myService.getClass().getInterfaces(), new MyInvocationHandler(myService));
        proxy.serve();
    }
}
  • CGlib动态代理
package com.it.zy.proxy.DynamicProxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
* @author zy
* @version 1.0
* @description : Cglib动态代理
* @date 2024/12/1 16:00
*/

class MyService2 {
    public void serve() {
        System.out.println("Serving...");
    }
}


class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method: " + method.getName());
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After method: " + method.getName());
        return result;
    }
}


public class CglibProxyDemo {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(MyService2.class);
        enhancer.setCallback(new MyMethodInterceptor());
        MyService2 proxy = (MyService2) enhancer.create();
        proxy.serve();
    }
}

总结

特性JDK动态代理CGLIB动态代理
代理的对象必须实现接口的类没有实现接口的类或接口
代理创建Proxy.newProxyInstance()Enhancer.create()
方法的调用InvocationHandler.invoke()MethodInterceptor.intercept()
限制目标类必须实现接口不能代理final类和final方法

相关知识点

  • 代理模式