代理模式的应用
前面简单介绍了下代理模式在 Java 中的三种不同使用方式。下面来介绍一个demo项目来加深理解代理模式的原理,方便更好的使用在多变的实际项目中。
项目背景
由于项目中会需要进行入参日志打印、处理结果打印、权限控制等业务逻辑处理,而这些业务逻辑功能又是多变的,如果都将这些业务逻辑放在主要逻辑之中,那么随着时间的增加,代码会越来越杂。
为了降低代码的耦合度,提高代码逻辑辨识。可以使用代理模式去抽离业务逻辑,将业务逻辑独立出来。
但是业务逻辑有时候也不会只有一种,例如某接口即需要入参打印,又需要权限处理,那么这类情况最好将不同的业务逻辑也进行拆分。
构建cglib代理
1. 目标方法
假设目标方法长这样:
public class ToolService {
public void run(String[] args) {
System.out.println("执行目标对象方法;args="+ Arrays.toString(args));
try {
Thread.sleep(100); // 模拟调用时长
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2. 子类代理回调的拦截器
如果使用cglib代理,那么需要先引用cglib的依赖。
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.10</version>
</dependency>
那么创建一回调拦截器,实现 MethodInterceptor
接口,用于处理子类代理调用方法时回调的逻辑,也即真正代理的逻辑。
public class ToolProxyCallback implements MethodInterceptor {
// 目标对象
private Object target;
public ToolProxyCallback(Object target) {
this.target = target;
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// 入参日志打印
System.out.println("准备执行目标方法;参数信息为="+args);
// 权限拦截
if(args.length <= 2) {
// 假设这里的权限是参数不能小于2个
return null;
}
// 通过反射执行目标方法
Object resultObj = method.invoke(target,args);
// 处理接口打印
System.out.println("目标方法请求结果为;"+resultObj);
return resultObj;
}
}
3. 创建子类代理的工厂
还需要一个工厂来创建子类代理的实例。
public class ToolProxyFactory<