文章目录
Java中的动态代理是一种设计模式,它允许在运行时创建代理对象,而不是在编译时。代理对象可以用来代理真实对象的方法调用。
Java中的动态代理主要有两种实现方式:JDK动态代理
和CGLIB动态代理
。
一、JDK动态代理
JDK动态代理使用Java标准库中的java.lang.reflect包来创建代理对象。它适用于实现了接口的类,通过接口类型来代理对象。
1、关键类和接口
- InvocationHandler接口:
这是一个接口,必须实现其invoke方法,代理对象的所有方法调用都会转发到这个方法。 - Proxy类:
这是一个用来创建代理对象的类,提供了静态方法newProxyInstance来生成代理对象。
2、实现步骤
1)定义接口和实现类:
java
public interface MyService {
void perform();
}
public class MyServiceImpl implements MyService {
@Override
public void perform() {
System.out.println("Executing perform method");
}
}
2)实现InvocationHandler接口,编写代理逻辑
java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public 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 method invoke");
Object result = method.invoke(target, args);
System.out.println("After method invoke");
return result;
}
}
3)使用Proxy.newProxyInstance方法创建代理对象
java
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
MyService myService = new MyServiceImpl();
MyInvocationHandler handler = new MyInvocationHandler(myService);
MyService proxyInstance = (MyService) Proxy.newProxyInstance(
myService.getClass().getClassLoader(),
myService.getClass().getInterfaces(),
handler
);
proxyInstance.perform();
}
}
二、CGLIB动态代理
CGLIB(Code Generation Library)是一种强大的字节码生成库,它允许在运行时创建子类,适用于没有实现接口的类。CGLIB通过继承被代理类来创建代理对象,因此无法代理final类。
1、关键类
- Enhancer类:
这是CGLIB用来生成代理类的主要类,通过设置超类和回调来创建代理对象。 - MethodInterceptor接口:
这是一个接口,类似于InvocationHandler,需要实现intercept方法。
2、实现步骤
1)添加CGLIB依赖:
在项目中添加CGLIB库的依赖。对于Maven项目:
xml
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
2)定义实现类:定义一个没有实现接口的类
java
public class MyService {
public void perform() {
System.out.println("Executing perform method");
}
}
3)实现MethodInterceptor,编写代理逻辑。
java
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("Before method invoke");
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method invoke");
return result;
}
}
4)使用Enhancer类创建代理对象。
java
import net.sf.cglib.proxy.Enhancer;
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyService.class);
enhancer.setCallback(new MyMethodInterceptor());
MyService proxyInstance = (MyService) enhancer.create();
proxyInstance.perform();
}
}
三、总结
- JDK动态代理:适用于实现了
接口
的类,通过InvocationHandler处理代理逻辑。 - CGLIB动态代理:适用于没有实现接口的类,通过
继承
实现代理,使用MethodInterceptor处理代理逻辑。性能更优。
动态代理在AOP(面向切面编程)、拦截器、权限控制、事务管理等领域有广泛应用,提供了灵活的方式来在运行时增强对象行为。