1、定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。
2、实现代码:
Chain接口
/**
* @Author: Liu Yue
* @Descripition:
* @Date; Create in 2020/3/14 22:23
**/
public interface Chain {
void next();
}
/**
* @Author: Liu Yue
* @Descripition:
* @Date; Create in 2020/3/16 8:53
**/
public class Member {
}
ChainHandler
/**
* @Author: Liu Yue
* @Descripition:
* @Date; Create in 2020/3/14 22:29
**/
public abstract class ChainHandler<T> {
protected ChainHandler next;
public void next(ChainHandler next) {
this.next = next;
}
public abstract void doHandler(Member member);
public static class Builder<T> {
private ChainHandler head = null;
private ChainHandler tail = null;
public Builder<T> addHandler(ChainHandler chain) {
if (this.head == null) {
this.head = this.tail = chain;
return this;
}
this.tail.next(chain);
this.tail = chain;
return this;
}
public ChainHandler<T> build() {
return this.head;
}
}
}
Chain实现类
/**
* @Author: Liu Yue
* @Descripition:
* @Date; Create in 2020/3/14 22:26
**/
public class FirstChain extends ChainHandler {
@Override
public void doHandler(Member member) {
System.out.println("第一个关口");
next.doHandler(member);
}
}
public class SecondChain extends ChainHandler {
@Override
public void doHandler(Member member) {
System.out.println("第二个关口");
next.doHandler(member);
}
}
public class ThirdChain extends ChainHandler {
@Override
public void doHandler(Member member) {
System.out.println("第三个关口");
if (member != null) {
next.doHandler(member);
}
}
}
客户端测试类
/**
* @Author: Liu Yue
* @Descripition:
* @Date; Create in 2020/3/16 8:49
**/
public class ChainTest1 {
public void chain(Member member) {
ChainHandler.Builder builder = new ChainHandler.Builder();
builder.addHandler(new FirstChain())
.addHandler(new SecondChain())
.addHandler(new ThirdChain());
builder.build().doHandler(member);
}
public static void main(String[] args) {
ChainTest1 chainTest1 = new ChainTest1();
chainTest1.chain(new Member());
}
}
3、servlet中的filter
public final class ApplicationFilterChain implements FilterChain {
private int pos = 0; //当前执行filter的offset
private int n; //当前filter的数量
private ApplicationFilterConfig[] filters; //filter配置类,通过getFilter()方法获取Filter
private Servlet servlet
@Override
public void doFilter(ServletRequest request, ServletResponse response) {
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = filterConfig.getFilter();
filter.doFilter(request, response, this);
} else {
// filter都处理完毕后,执行servlet
servlet.service(request, response);
}
}
}
4、dubbo中的filter
Dubbo在创建Filter的时候是另外一个方法,通过把Filter封装成 Invoker的匿名类,通过链表这样的数据结构来完成责任链。
Dubbo的责任链就没有类似FilterChain这样的类吧Filter和调用Invoker结合起来,而是通过创建一个链表,调用的时候我们只知道第一个节点,每个节点包含了下一个调用的节点信息。 这里的虽然Invoker封装Filter没有显示的指定next,但是通过java匿名类和final的机制达到同样的效果。
5、mybatis中的plugin
Mybatis可以配置各种Plugin,无论是官方提供的还是自己定义的,Plugin和Filter类似,就在执行Sql语句的时候做一些操作。Mybatis的责任链则是通过动态代理的方式,使用Plugin代理实际的Executor类。(这里实际还使用了组合模式,因为Plugin可以嵌套代理),核心代码如下:
public class Plugin implements InvocationHandler{
private Object target;
private Interceptor interceptor;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (满足代理条件) {
return interceptor.intercept(new Invocation(target, method, args));
}
return method.invoke(target, args);
}
//对传入的对象进行代理,可能是实际的Executor类,也可能是Plugin代理类
public static Object wrap(Object target, Interceptor interceptor) {
Class<?> type = target.getClass();
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) {
return Proxy.newProxyInstance(
type.getClassLoader(),
interfaces,
new Plugin(target, interceptor, signatureMap));
}
return target;
}
}
感谢博主: https://www.cnblogs.com/z-test/p/9319116.html
每天提高一点点