1. 程式人生 > >spring aop學習9:Aop的鏈式呼叫(責任鏈模式)

spring aop學習9:Aop的鏈式呼叫(責任鏈模式)

一.責任鏈模式
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);
        }
    }