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