责任链模式--Spring-AOP

责任链模式–Spring AOP

责任链模式是一个链,链上分布着若该节点,当请求过来时,第一个节点处理,然后交给下个节点处理,一直到链结尾。

分析Spring AOP 责任链模式实现

1:在代码中声明Spring AOP切点时,会给目标类生成代理对象,同时生成责任链 (protected final List<?> interceptorsAndDynamicMethodMatchers;)
2:在调用目标方法时,会调入ReflectiveMethodInvocation中的proceed方法,开始责任链调用,此时,责任链已经生成,如下图
tomcat-load

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* Index from 0 of the current interceptor we're invoking.
* -1 until we invoke: then the current interceptor.
*/
private int currentInterceptorIndex = -1;

/**
* 责任调用链
*/
protected final List<?> interceptorsAndDynamicMethodMatchers;

public Object proceed() throws Throwable {
// currentInterceptorIndex 初始值为-1
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//每次调用会比较当前责任链是否完毕,如果完了,调用目标方法
return invokeJoinpoint();
}
// 调用一次currentInterceptorIndex加1
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// 递归调用开始
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

*AOP 责任链默认排序 * ExposeInvocationInterceptor – 把当前调用链名称放入ThreadLocal
AspectJAfterThrowingAdvice – 异常通知
AfterReturningAdviceInterceptor – 返回通知
AspectJAfterAdvice – 后置通知(如果前置通知或目标方法异常仍会执行)
MethodBeforeAdviceInterceptor – 前置通知
递归调用流程如图:
tomcat-load

根据理解自己实现一个责任链

1:定义一个接口,各节点需要实现自己要做的事情

1
2
3
4
5
6
package com.java.proxy.ResponsibilityChain;

public interface BaseMethodInvocation {

void proceed(BaseMethodInvocation baseMethodInvocation);
}

2:定义调用链封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.java.proxy.ResponsibilityChain;

import java.util.ArrayList;
import java.util.List;

public class MethodChainFactory implements BaseMethodInvocation {


public List<BaseMethodInvocation> chainList = new ArrayList<>();

public static Integer index = -1;

public MethodChainFactory addBaseMethodInvocation (BaseMethodInvocation baseMethodInvocation) {
chainList.add(baseMethodInvocation);
// 返回MethodChainFactory 为了链式调用
return this;
}


@Override
public void proceed(BaseMethodInvocation baseMethodInvocation) {

if(index == chainList.size()-1){
return ;
}
BaseMethodInvocation methodInvocation = chainList.get(++index);
methodInvocation.proceed(this);
}
}

3:测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.java.proxy.ResponsibilityChain;

public class TestChain {



static class TwoChain implements BaseMethodInvocation {
@Override
public void proceed(BaseMethodInvocation baseMethodInvocation) {
System.out.println("第二个链执行。。。。");
//调用下一个链
baseMethodInvocation.proceed(this);
}
}

static class OneChain implements BaseMethodInvocation {
@Override
public void proceed(BaseMethodInvocation baseMethodInvocation) {
System.out.println("第一个链执行。。。。");
//调用下一个链
baseMethodInvocation.proceed(this);
}
}



public static void main(String[] args) {

MethodChainFactory methodChainFactory = new MethodChainFactory();
methodChainFactory.addBaseMethodInvocation(new OneChain())
.addBaseMethodInvocation(new TwoChain());
methodChainFactory.proceed(methodChainFactory);
}

}

结果:
第一个链执行。。。。
第二个链执行。。。。

这只是一个简单的责任链,工作中要根据实际的需求来具体实现,比如传参,执行顺序等。