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