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

文章标题:100道Java面试题之-Java中的动态代理(Dynamic Proxy)是什么?它如何实现?
  • 文章分类: 后端
  • 3816 阅读
### 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动态代理示例**: ```java 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库): ```java 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
推荐文章