spring aop學習9:Aop的鏈式呼叫(責任鏈模式)
阿新 • • 發佈:2019-02-08
一.責任鏈模式
1.基本的責任鏈模式
◆主體父類:abstract class Subject.java
package com.tiglle.responsibility.chain.model;
//主體
public abstract class Subject {
private Subject successor;
protected abstract void handle();
public void execute(){
handle();
if(successor!=null){
successor.execute();
}
}
public Subject getSuccessor() {
return successor;
}
public void setSuccessor(Subject successor) {
this.successor = successor;
}
}
◆子類和測試main方法:MainExec.java
package com.tiglle.responsibility.chain.model;
public class MainExec {
private static class Part1 extends Subject {
@Override
protected void handle() {
System.out.println("Part1的handle");
}
}
private static class Part2 extends Subject{
@Override
protected void handle() {
System.out.println("Part2的handle");
}
}
private static class Part3 extends Subject{
@Override
protected void handle() {
System.out.println("Part3的handle");
}
}
public static void main(String[] args) {
Part1 part1 = new Part1();
Part2 part2 = new Part2();
Part3 part3 = new Part3();
part1.setSuccessor(part2);
part2.setSuccessor(part3);
part1.execute();
}
}
執行結果:
Part1的handle
Part2的handle
Part3的handle
原理:
執行Part1繼承自父類的execute()方法,首先執行Part1重寫了父類抽象方法handle(),然後判斷successor(此時successor為Part2)是否為null
此時successor(Part2)不為null,執行Part2的execute,首先執行Part2重寫了父類抽象方法handle(),然後判斷successor(此時successor為Part3)是否為null
此時successor(Part3)不為null,執行Part3的execute,首先執行Part3重寫了父類抽象方法handle(),然後判斷successor(Part3的successor為null)是否為null,為null,停止執行
2.優化的責任鏈模式
◆主體父類:abstract class Subject.java
package com.tiglle.responsibility.chain.model.optimization;
public abstract class Subject {
protected abstract void handle();
public void execute(SubjectChain successor){
handle();
successor.process();
}
}
◆中間類:class SubjectChain.java
package com.tiglle.responsibility.chain.model.optimization;
import java.util.List;
public class SubjectChain {
private List<Subject> successors;
public SubjectChain(List<Subject> successors){
this.successors = successors;
}
private int index = 0;
public void process(){
if(index < successors.size()){
successors.get(index++).execute(this);
}
}
}
◆測試main方法:MainExec.java
package com.tiglle.responsibility.chain.model.optimization;
import java.util.ArrayList;
import java.util.List;
public class MainExec {
private static class Part1 extends Subject{
@Override
protected void handle() {
System.out.println("Part1的handle");
}
}
private static class Part2 extends Subject{
@Override
protected void handle() {
System.out.println("Part2的handle");
}
}
private static class Part3 extends Subject{
@Override
protected void handle() {
System.out.println("Part3的handle");
}
}
public static void main(String[] args) {
Part1 part1 = new Part1();
Part2 part2 = new Part2();
Part3 part3 = new Part3();
List<Subject> successors = new ArrayList<>();
successors.add(part1);
successors.add(part2);
successors.add(part3);
SubjectChain subjectChain = new SubjectChain(successors);
subjectChain.process();
}
}
執行結果:
Part1的handle
Part2的handle
Part3的handle
原理:兩個方法的互相呼叫,並設定中斷條件
二.spring aop的鏈式呼叫使用的第二種方法:
原始碼:
@Override
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//從-1開始每次加1
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
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 {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}