返回

看不见的守护者:动态代理的实现与原理分析

后端

动态代理是一种面向切面编程(AOP)的技术,它允许您在不修改现有代码的情况下,为对象添加新行为。动态代理经常用于实现诸如日志记录、安全检查和缓存之类的功能。

JDK提供了两种实现动态代理的方式:接口代理和子类代理。接口代理是通过实现一个或多个接口来创建代理对象,而子类代理是通过扩展一个类来创建代理对象。

以下是一个使用JDK接口代理实现动态代理的示例:

public interface IHello {
    void sayHello();
}

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

public class DynamicProxyHandler implements InvocationHandler {
    private Object target;

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

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

public class Main {
    public static void main(String[] args) {
        IHello hello = (IHello) Proxy.newProxyInstance(
                IHello.class.getClassLoader(),
                new Class[]{IHello.class},
                new DynamicProxyHandler(new HelloImpl())
        );

        hello.sayHello();
    }
}

在这个示例中,IHello接口定义了一个sayHello()方法,HelloImpl类实现了IHello接口,DynamicProxyHandler类实现了InvocationHandler接口,Main类创建了一个IHello的动态代理对象,并调用了sayHello()方法。

当调用sayHello()方法时,代理对象会将方法调用委托给InvocationHandlerinvoke()方法,InvocationHandlerinvoke()方法会在方法调用前后执行一些额外的逻辑,在本示例中,InvocationHandlerinvoke()方法会在方法调用前后打印一些日志信息。

动态代理的原理

动态代理的原理是使用反射机制来创建代理对象。当创建一个代理对象时,动态代理类会创建一个新的类,这个新的类继承了目标类并实现了目标接口,然后动态代理类会使用反射机制来创建代理对象的实例。

代理对象的实例可以调用目标对象的方法,当代理对象的方法被调用时,代理对象会将方法调用委托给目标对象。

JDK动态代理与CGLIB动态代理的区别

JDK动态代理和CGLIB动态代理都是实现动态代理的两种方式,它们的主要区别在于:

  • JDK动态代理只能代理实现了接口的类,而CGLIB动态代理可以代理任何类。
  • JDK动态代理创建的代理对象是一个新的类,而CGLIB动态代理创建的代理对象是目标类的子类。
  • JDK动态代理的性能比CGLIB动态代理要高。

总结

动态代理是一种面向切面编程(AOP)的技术,它允许您在不修改现有代码的情况下,为对象添加新行为。动态代理经常用于实现诸如日志记录、安全检查和缓存之类的功能。

JDK提供了两种实现动态代理的方式:接口代理和子类代理。接口代理是通过实现一个或多个接口来创建代理对象,而子类代理是通过扩展一个类来创建代理对象。

JDK动态代理和CGLIB动态代理都是实现动态代理的两种方式,它们的主要区别在于:

  • JDK动态代理只能代理实现了接口的类,而CGLIB动态代理可以代理任何类。
  • JDK动态代理创建的代理对象是一个新的类,而CGLIB动态代理创建的代理对象是目标类的子类。
  • JDK动态代理的性能比CGLIB动态代理要高。