定义
代理对象作为客户端和真实对象之间的中介,替代真实对象处理请求,实现对访问的控制和功能增强。客户端通过代理间接操作真实对象,二者通常实现相同接口。
结构
适用场景
1)远程代理为一个对象在不同的地址空间提供局部代表
2)虚拟代理根据需要创建开销很大的对象
3)安全代理控制对原始对象的访问
4)日志代理记录操作行为
使用实例
这里以日志代理为例,说明java中代理的几种方式。
1、静态代理
2、JDK动态代理
3、Cglib代理
/**
* 定义业务接口
*/
public interface UserService {
void addUser(String username);
void deleteUser(String userId);
}
public class UserServiceImpl implements UserService{
@Override
public void addUser(String username) {
System.out.println("真实操作:添加用户 " + username);
}
@Override
public void deleteUser(String userId) {
System.out.println("真实操作:删除用户ID " + userId);
}
}
/**
* 定义静态代理类
*/
public class UserServiceProxy implements UserService {
private final UserService target;
public UserServiceProxy(UserService target) {
this.target = target;
}
@Override
public void addUser(String username) {
System.out.println("静态代理,【前置日志】调用addUser,参数: " + username);
target.addUser(username); // 调用真实对象
System.out.println("静态代理,【后置日志】addUser执行完成");
}
@Override
public void deleteUser(String userId) {
System.out.println("静态代理,【前置日志】调用deleteUser,参数: " + userId);
target.deleteUser(userId);
System.out.println("静态代理,【后置日志】deleteUser执行完成");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 定义JDK动态代理核心处理类
*/
public class LoggingHandler implements InvocationHandler {
private final Object target;
public LoggingHandler(Object target) {
if (target == null) {
throw new IllegalArgumentException("Target object cannot be null");
}
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK,调用方法: " + method.getName());
return method.invoke(target, args);
}
}
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
/**
* 定义Cglib代理核心处理类
*/
public class LogInterceptor implements MethodInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
logger.info("Cglib,方法调用开始 => {}.{}()", obj.getClass().getSuperclass().getSimpleName(), method.getName());
Object result = proxy.invokeSuper(obj, args);
logger.info("Cglib,方法调用结束 <= {}", method.getName());
return result;
}
}
测试
import net.sf.cglib.proxy.Enhancer;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
// 静态代理
UserService realService = new UserServiceImpl();
UserService proxy = new UserServiceProxy(realService);
proxy.addUser("张三");
proxy.deleteUser("100001");
// jdk动态代理
UserService jdkProxy = (UserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(),
new Class[]{UserService.class},
new LoggingHandler(realService)
);
jdkProxy.addUser("Alice");
jdkProxy.deleteUser("100002");
// Cglib代理(针对类)
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback(new LogInterceptor());
UserService cglibProxy = (UserService) enhancer.create();
cglibProxy.addUser("张五");
cglibProxy.deleteUser("100003");
}
}