Java代理模式
使用代理对象来代替真正的目标对象,既能实现原有目标对象的功能,还能在不修改目标对象的情况下,增加额外的功能。
静态代理
每一个目标类对应一个代理类,当目标类新增方法时,代理类也需要新增一个方法,每个方法的增强都是手动完成的
步骤:
- 创建一个接口和对应的实现类
- 创建一个代理类同样实现这个接口
- 将目标类注入代理类,调用目标类的方法
JDK动态代理
Java中的动态代理是一种在运行时创建代理对象的机制,动态代理允许程序在运行是决定代理对象的行为,而不需要在编译时确定。
工作原理:
- 代理接口:定义一个接口,代理对象和目标对象都实现这个接口
- 创建一个类实现InvocationHandler接口:在java中,使用InvocationHandler接口来定义代理行为,需要实现这个接口并且重写接口的invoke方法,该方法在调用真实对象的时候会触发
- Proxy类,使用java的Proxy类的newProxyInstance方法来动态创建动态代理对象。
- 定义接口
public interface UserService {
void addUser(String user);
}
- 实现接口
public class UserServiceImpl implements UserService {
@Override
public void addUser(String user) {
System.out.println("添加用户: " + user);
}
}
- 创建InvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
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("代理前的处理...");
// 调用真实对象的方法
Object result = method.invoke(target, args);
// 代理后的处理
System.out.println("代理后的处理...");
return result;
}
}
- 创建代理对象
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
// 创建代理对象
UserService proxyInstance = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
new DynamicProxyHandler(userService)
);
// 使用代理对象
proxyInstance.addUser("张三");
}
}
CGLIB动态代理
JDK动态代理有一个致命的问题,就是只能代理实现了接口的类
CGLIB基于ASM字节码生成工具,通过继承的方式来实现代理类,所以不需要接口,可以代理普通的类
工作原理:
CGLIB通过继承目标类来创建一个子类,并重写方法,在方法调用前后插入自己的逻辑
步骤:
- 添加CHLIB依赖
- 创建目标类
- 创建MethodInterceptor:实现
MethodInterceptor接口,重写intercept方法以定义代理行为。 - 创建代理对象:使用CGLIB的Enhancer类来创建代理对象
1.
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
2.
public class UserService {
public void addUser(String user) {
System.out.println("添加用户: " + user);
}
}
3.
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class UserServiceInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 代理前的处理
System.out.println("代理前的处理...");
// 调用目标类的方法
Object result = proxy.invokeSuper(obj, args);
// 代理后的处理
System.out.println("代理后的处理...");
return result;
}
}
4.
import net.sf.cglib.proxy.Enhancer;
public class Main {
public static void main(String[] args) {
// 创建CGLIB的Enhancer对象
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class); // 设置需要代理的目标类
enhancer.setCallback(new UserServiceInterceptor()); // 设置代理逻辑
// 创建代理对象
UserService proxyInstance = (UserService) enhancer.create();
// 使用代理对象
proxyInstance.addUser("李四");
}
}
