当前位置: 技术文章>> 100道Java面试题之-Java中的动态代理(Dynamic Proxy)是什么?它如何实现?

文章标题:100道Java面试题之-Java中的动态代理(Dynamic Proxy)是什么?它如何实现?
  • 文章分类: 后端
  • 3893 阅读

Java中的动态代理(Dynamic Proxy)是什么?

Java中的动态代理是一种在运行时动态生成代理类及其对象的技术。它主要用于实现AOP(面向切面编程)的思想,允许开发者在不修改原始类代码的情况下,增加新的功能或行为。动态代理通常用于实现接口,通过接口定义业务方法,并在运行时动态为接口生成实现类。这种方式使得客户端代码与真实对象之间多了一层代理对象,代理对象可以拦截客户端请求并进行一些额外处理(如添加日志、权限校验等),然后再将请求转发给真实对象处理。

动态代理如何实现?

在Java中,实现动态代理主要有两种方式:

  1. 使用JDK提供的Proxy类和InvocationHandler接口

    • InvocationHandler接口:定义了代理对象需要实现的方法,即invoke(Object proxy, Method method, Object[] args)方法,用于在代理对象上调用方法时执行额外的逻辑。
    • Proxy类:提供了用于创建动态代理类的静态方法newProxyInstance(),该方法接收三个参数:类加载器(ClassLoader)、被代理对象的接口数组(Class<?>[] interfaces)以及InvocationHandler实现类的实例。

    具体实现步骤如下:

    • 为需要代理的接口创建一个InvocationHandler实现类,并在其invoke()方法中编写代理逻辑。
    • 使用Proxy.newProxyInstance()方法生成代理对象,该对象实现了我们需要代理的接口,并将所有方法调用都委托给了InvocationHandler实现类中的invoke()方法。
  2. 使用CGLIB库

    CGLIB(Code Generation Library)是一个强大的、高性能、高质量的代码生成类库,它可以在运行时扩展Java类和实现Java接口。与JDK动态代理不同,CGLIB通过构建继承类来实现动态代理。

    • Enhancer类:是CGLIB中实现动态代理的关键类,通过它我们可以为目标类创建代理类。
    • MethodInterceptor接口:类似于JDK中的InvocationHandler接口,但CGLIB中的代理逻辑是在intercept(Object obj, Method method, Object[] args, MethodProxy proxy)方法中实现的。

    具体实现步骤如下:

    • 创建一个Enhancer对象,并设置其父类(即目标类)。
    • 设置代理实现逻辑,即实现MethodInterceptor接口的intercept()方法。
    • 调用Enhancer对象的create()方法生成代理对象。

示例代码

JDK动态代理示例

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

interface Hello {
    void sayHello();
}

class HelloImpl implements Hello {
    @Override
    public void sayHello() {
        System.out.println("Hello World");
    }
}

class MyInvocationHandler implements InvocationHandler {
    private 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 invoking sayHello()");
        Object result = method.invoke(target, args);
        System.out.println("After invoking sayHello()");
        return result;
    }
}

public class DynamicProxyDemo {
    public static void main(String[] args) {
        Hello hello = new HelloImpl();
        InvocationHandler handler = new MyInvocationHandler(hello);
        Hello proxy = (Hello) Proxy.newProxyInstance(
                hello.getClass().getClassLoader(),
                hello.getClass().getInterfaces(),
                handler
        );
        proxy.sayHello();
    }
}

CGLIB动态代理示例(需要引入CGLIB库):

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

class TargetObject {
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

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

public class CglibProxyDemo {
    public static void main(String[] args
推荐文章