代理模式属于结构性模式。结构性模式主要总结了一些类或者对象组合在一起的经典结构
代理模式。在不改变原始类的代码逻辑情况下通过引入代理类来给原始类附加功能。
分为两种:静态代理和动态代理
静态代理:为业务实现类AService,创建一个对应的AServiceProxy,在AServiceProxy中添加代理额外的工作内容
动态代理:运行时为被代理对象AService生成一个代理对象,在执行AService的方法时,添加代理的额外工作
实际的业务逻辑:
public class UserController {
private MetricsController metricsCollector;
public void login(String telephone, String password) {
long startTimestamp = System.currentTimeMillis();
// ... 省略login逻辑...
long endTimeStamp = System.currentTimeMillis();
long responseTime = endTimeStamp - startTimestamp;
RequestInfo requestInfo = new RequestInfo("login", responseTime, startTimestamp);
metricsCollector.recordRequest(requestInfo);
//...返回UserVo数据... }
}
}
代理需要在基于业务逻辑的基础上穿插的操作内容:
public class MetricsController {
// 实现接口请求的上报
public void recordRequest(RequestInfo requestInfo) {}
}
模拟生成代理对象的类:
public class UserControllerProxy {
@Resource
private MetricsController metricsController;
public UserControllerProxy() {
}
public UserControllerProxy(MetricsController metricsController) {
this.metricsController = metricsController;
}
// 参数是被代理的对象
public Object createProxy(Object proxiedObject) {
// 获取对象实现的所有接口列表
Class<?>[] interfaces = proxiedObject.getClass().getInterfaces();
DynamicProxyHandler dynamicProxyHandler = new DynamicProxyHandler(proxiedObject);
return Proxy.newProxyInstance(proxiedObject.getClass().getClassLoader(), interfaces, dynamicProxyHandler);
}
public class DynamicProxyHandler implements InvocationHandler {
// 被代理的对象
private Object proxiedObject;
public DynamicProxyHandler(Object proxiedObject) {
this.proxiedObject = proxiedObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime =System.currentTimeMillis();
// 执行被代理的对象的方法
Object invoke = method.invoke(proxiedObject, args);
long endTime = System.currentTimeMillis();
long responseTime = endTime - startTime;
// 拼接方法名
String apiName = proxiedObject.getClass().getName() + "_" + method.getName();
RequestInfo requestInfo = new RequestInfo(apiName, responseTime, startTime);
// 额外上报功能的实现
metricsController.recordRequest(requestInfo);
return invoke;
}
}
}