Aop通知调用链源码分析
责任链模式
public interface GatewayHandler {
/**
* Boolean返回类型的作用是干嘛? 使用递归停止下一步
*/
public Boolean service();
}
public class BlacklistHandler implements GatewayHandler {
public Boolean service() {
System.out.println(">>>第二关 黑名单拦截");
return true;
}
}
public class CurrentLimitHandler implements GatewayHandler {
public Boolean service() {
System.out.println("第一关>>>api接口的限流");
return true;
}
}
核心实现
public class GatewayHandlerUtils {
private List<GatewayHandler> listGatewayHandler;
private int index;
public GatewayHandlerUtils() {
listGatewayHandler = new ArrayList<GatewayHandler>();
listGatewayHandler.add(new CurrentLimitHandler());
listGatewayHandler.add(new BlacklistHandler());
}
public void invoke() {
for (int i = 0; i < listGatewayHandler.size(); i++) {
GatewayHandler gatewayHandler = listGatewayHandler.get(i);
Boolean service = gatewayHandler.service();
if (!service) {
return;
}
}
}
public void recurrenceInvoke() {
// 大数据批量拆分 百万级消息群发 每次只发送一万条
if (index == listGatewayHandler.size()) {
return;
}
GatewayHandler gatewayHandler = listGatewayHandler.get(index++);
Boolean service = gatewayHandler.service();
if (!service) {
return;
}
recurrenceInvoke();
}
}
测试
public class Test {
public static void main(String[] args) {
GatewayHandlerUtils gatewayHandlerUtils = new GatewayHandlerUtils();
gatewayHandlerUtils.recurrenceInvoke();
}
}
aop 中使用责任链执行通知
- 注入 AnnotationAwareAspectJAutoProxyCreator–>AbstractAutoProxyCreator–> postProcessAfterInitialization (方法) --> wrapIfNecessary (方法) --> JdkDynamicAopProxy
- 执行时调用 invoke 方法
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
proceed() 方法
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
手动实现 aop 责任链
定义 Interceptor
public interface MethodInterceptor {
/**
* 定义共同通知骨架
*/
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException;
}
public class BeforMethodInterceptor implements MethodInterceptor {
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
System.out.println(">>>>前置通知<<<<");
// 执行我们的目标方法
methodInvocation.process();// 递归调用
}
}
public class AroundMethodInterceptor implements MethodInterceptor {
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
System.out.println("环绕通知在目标方法之前执行..");
methodInvocation.process();
System.out.println("环绕通知在目标方法之后执行..");
}
}
public class AfterMethodInterceptor implements MethodInterceptor {
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
// 执行我们的前置通知
methodInvocation.process();
System.out.println(">>>后置通知<<<");
}
}
定义 Invocation
public interface MethodInvocation {
// 能够把通知链形成关联
public void process() throws InvocationTargetException, IllegalAccessException;
}
public class DefaultMethodInvacation implements MethodInvocation {
/**
* 存放所有的通知
*/
private List<MethodInterceptor> listMethodInterceptor;
private Object target;// 目标对象
private Method method;// 目标方法
private Object args[];// 目标参数
// 最终使用反射机制执行目标方法
private int index;// 记录当前链调用的位置
public DefaultMethodInvacation(List<MethodInterceptor> listMethodInterceptor, Object target, Method method, Object[] args) {
this.listMethodInterceptor = listMethodInterceptor;
this.target = target;
this.method = method;
this.args = args;
}
public DefaultMethodInvacation(List<MethodInterceptor> listMethodInterceptor) {
this.listMethodInterceptor = listMethodInterceptor;
}
/**
* 调用链形成
*/
public void process() throws InvocationTargetException, IllegalAccessException {
if (index == listMethodInterceptor.size()) {//做了一个指针,很妙
method.invoke(target, args); // 执行目标
return;
}
MethodInterceptor methodInterceptor = listMethodInterceptor.get(index++);
methodInterceptor.invoke(this);
}
}
核心业务 service
public class UserService {
public void login(String userName, Integer age) {
System.out.println("userName:" + userName + ",age:" + age);
}
}
调用测试
public class Test00 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// 1.装配所有的通知存放到集合中
ArrayList<MethodInterceptor> methodInterceptors = new ArrayList<MethodInterceptor>();
methodInterceptors.add(new BeforMethodInterceptor());
methodInterceptors.add(new AfterMethodInterceptor());
methodInterceptors.add(new AroundMethodInterceptor());
// new MethodInvocation(methodInterceptors).process();
// 2.创建我们的目标方法
UserService userService = new UserService();
Method loginMethod = UserService.class.getMethod("login", String.class, Integer.class);
Object[] objects = {"mayikt", 12};
new DefaultMethodInvacation(methodInterceptors, userService, loginMethod, objects).process();
// SpringAop底层 所有的通知最终使用递归算法调用+责任链设计模式
// 第一关 APi接口限流 第二关 黑名单拦截
}
}