内容简介:多个对象都有机会处理请求,将这些对象连成一个链,将请求沿着这条链传递,直到有对象处理为止。纯的责任链模式是如果被处理者进行处理了,则请求传递结束。OkHttp的拦截器是不纯的责任链模式,在请求到达时,拦截器会做一些处理(比如添加参数等),然后传递给下一个拦截器进行处理。在请求过程中,通过拦截器对请求进行处理
多个对象都有机会处理请求,将这些对象连成一个链,将请求沿着这条链传递,直到有对象处理为止。
2、使用场景
- 多个对象处理同一请求,具体哪个对象处理需要动态决定
- 需要指定一组对象处理请求
3、优点
- 将处理者和请求者进行解耦
4、缺点
- 需要对处理者进行遍历,处理者过多会影响性能
5、类图
- Handler:抽象处理者,声明请求处理的方法,并保持对下一个处理节点Handler的引用
- ConcreteHandler:具体处理者,对请求进行处理,如果不能处理将请求转发给下一个节点
二、实例
1、抽象类Handler
/**
* @Description 抽象处理者
*/
public abstract class Handler {
//下一个处理者
private Handler mNextHandler;
public Handler(){
}
/**
* 传入下一个处理者
* @param nextHandler
*/
public Handler(Handler nextHandler) {
this.mNextHandler = nextHandler;
}
/**
* 处理请求
*/
public final void handleRequest(Request request) {
//请求者和处理者级别相同才进行处理
if (getCurLevel() == request.getRequestLevel()) {
handle(request);
} else {
//否则将请求交给下一个处理者
if (mNextHandler != null) {
mNextHandler.handleRequest(request);
} else {
System.out.print("无人处理");
}
}
}
/**
* 获取处理者的级别
* @return
*/
protected abstract int getCurLevel();
/**
* 当前处理者处理的逻辑
* @param request
*/
protected abstract void handle(Request request);
}
复制代码
2、具体处理者
public class HandlerA extends Handler {
public HandlerA(Handler nextHandler) {
super(nextHandler);
}
@Override
protected int getCurLevel() {
return 6;
}
@Override
protected void handle(Request request) {
System.out.print("HandlerA 进行处理");
}
}
复制代码
public class HandlerB extends Handler {
public HandlerB() {
}
public HandlerB(Handler nextHandler) {
super(nextHandler);
}
@Override
protected int getCurLevel() {
return 10;
}
@Override
protected void handle(Request request) {
System.out.print("HandlerB 进行处理");
}
}
复制代码
3、抽象请求
public abstract class Request {
/**
* @return 请求的级别
*/
public abstract int getRequestLevel();
}
复制代码
4、具体请求
public class RequestA extends Request {
@Override
public int getRequestLevel() {
return 10;
}
}
复制代码
5、使用
public class HandlerTest {
public static void main(String[] args) {
RequestA request = new RequestA();
//最后一个处理者
Handler handlerB = new HandlerB();
//第一个处理者
Handler handlerA = new HandlerA(handlerB);
//最终传递到HandlerB处理
handlerA.handleRequest(request);
}
}
复制代码
三、OkHttp的Interceptor
纯的责任链模式是如果被处理者进行处理了,则请求传递结束。OkHttp的拦截器是不纯的责任链模式,在请求到达时,拦截器会做一些处理(比如添加参数等),然后传递给下一个拦截器进行处理。
1、请求拦截处理
在请求过程中,通过拦截器对请求进行处理
Response response = getResponseWithInterceptorChain(); 复制代码
Response getResponseWithInterceptorChain() throws IOException {
// 创建拦截器的list
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
// 创建RealInterceptorChain,传入的index索引为0
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
复制代码
创建首个RealInterceptorChain对象,并传入拦截器的集合,通过proceed进行请求的处理。
2、请求处理
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
......
// 创建下一个RealInterceptorChain,将index+1(下一个拦截器索引)传入
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
//获取当前的拦截器
Interceptor interceptor = interceptors.get(index);
//通过Interceptor的intercept进行处理
Response response = interceptor.intercept(next);
......
return response;
}
复制代码
- 创建下一个RealInterceptorChain对象,并将当前RealInterceptorChain中的变量当成参数传入,并将索引index+1传入。
- 获取当前index位置上的拦截器,第一次创建时传入的index为0,表示获取第一个拦截器,后面会将index+1进入传入,用于获取下一个拦截器。
- 在Interceptor的intercept中,将下一个RealInterceptorChain传入,内部会调用下一个RealInterceptorChain的proceed方法
3、Interceptor接口
public interface Interceptor {
/**
* 拦截Chain,并触发下一个拦截器的调用
* @param chain 被处理的对象
* @return
* @throws IOException
*/
Response intercept(Chain chain) throws IOException;
interface Chain {
//返回请求
Request request();
//对请求进行处理
Response proceed(Request request) throws IOException;
......
}
}
复制代码
4、ConnectInterceptor
public final class ConnectInterceptor implements Interceptor {
public final OkHttpClient client;
public ConnectInterceptor(OkHttpClient client) {
this.client = client;
}
@Override public Response intercept(Chain chain) throws IOException {
//下一个拦截链
RealInterceptorChain realChain = (RealInterceptorChain) chain;
//获取Request进行处理
Request request = realChain.request();
StreamAllocation streamAllocation = realChain.streamAllocation();
// We need the network to satisfy this request. Possibly for validating a conditional GET.
boolean doExtensiveHealthChecks = !request.method().equals("GET");
HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks);
RealConnection connection = streamAllocation.connection();
//会调用下一个拦截链的proceed进行处理
return realChain.proceed(request, streamAllocation, httpCodec, connection);
}
}
复制代码
ConnectInterceptor作为一个具体的处理者,接收到下一个RealInterceptorChain对象,通过RealInterceptorChain的proceed方法对请求进行处理。
整个链式调用的流程为:
首个Chain procced--首个Interceptor interceptor--
下一个Chain procced--下一个Interceptor interceptor--
下一个Chain procced--下一个Interceptor interceptor....
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 设计模式——订阅模式(观察者模式)
- 设计模式-简单工厂、工厂方法模式、抽象工厂模式
- java23种设计模式-门面模式(外观模式)
- 设计模式-享元设计模式
- Java 设计模式之工厂方法模式与抽象工厂模式
- JAVA设计模式之模板方法模式和建造者模式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Music Recommendation and Discovery
Òscar Celma / Springer / 2010-9-7 / USD 49.95
With so much more music available these days, traditional ways of finding music have diminished. Today radio shows are often programmed by large corporations that create playlists drawn from a limited......一起来看看 《Music Recommendation and Discovery》 这本书的介绍吧!