使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
请求和处理分开、实现解耦、提高系统的灵活性
可以动态的调整请求的链条,增加系统灵活性
职责链模式每个执行者都包含了另一个执行者的引用。如果一个对象不能处理该请求,会把请求传递给下一个执行者。
客户端需要动态的调整,执行者的上下级。
Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。
/**
* 处理请求的抽象类
*
* @author Promsing(张有博)
* @version 1.0.0
* @since 2022/9/7 - 9:29
*/
public abstract class Handler {
//维持一个下一个执行者的引用
protected Handler handler;
protected void setHandler(Handler handler) {
this.handler = handler;
}
//处理请求的抽象方法
public abstract void processRequest(int request);
}
/**
* 只处理数字1-10
*
* @author Promsing(张有博)
* @version 1.0.0
* @since 2022/9/7 - 9:31
*/
public class ConcreteHandlerA extends Handler{
@Override
public void processRequest(int request) {
if (request>=0 && request<10 ){
System.out.println("ConcreteHandlerA已经处理完毕了 "+request);
return;
}
if (handler!=null){
//下一位处理
handler.processRequest(request);
}
}
}
/**
* 只处理数字10-20
*
* @author Promsing(张有博)
* @version 1.0.0
* @since 2022/9/7 - 9:31
*/
public class ConcreteHandlerB extends Handler{
@Override
public void processRequest(int request) {
if (request>=10 && request<20 ){
System.out.println("ConcreteHandlerB已经处理完毕了 "+request);
return;
}
if (handler!=null){
//下一位处理
handler.processRequest(request);
}
}
}
/**
*只处理数字30+
*
* @author Promsing(张有博)
* @version 1.0.0
* @since 2022/9/7 - 9:31
*/
public class ConcreteHandlerC extends Handler{
@Override
public void processRequest(int request) {
if (request>=30 ){
System.out.println("ConcreteHandlerC已经处理完毕了 "+request);
return;
}
if (handler!=null){
//下一位处理
handler.processRequest(request);
}
}
}
public class Main {
public static void main(String[] args) {
//创建执行者
Handler h1=new ConcreteHandlerA();
Handler h2=new ConcreteHandlerB();
Handler h3=new ConcreteHandlerC();
//设置向下级的顺序,可根据配置动态设置上下级
h1.setHandler(h2);
h2.setHandler(h3);
int[] requests={8,11,23,50,7,19,28,40};
//循环处理请求,不同的数值,交给不同的执行者
for (int request : requests) {
h1.processRequest(request);
}
}
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;//请求
HandlerExecutionChain mappedHandler = null;//执行链
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest); //根据请求-获得执行链
//判断mappedHandler是否为空,空:404
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 确定当前请求的处理程序适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//职责链的前置拦截
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//执行handler方法-controller
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//职责链的后置拦截
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
//对结果集进行处理
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
//执行完成了拦截器
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
finally {
//资源释放
}
}
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors(); //获得拦截器
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {//循环遍历执行前置拦截
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
throws Exception {
HandlerInterceptor[] interceptors = getInterceptors(); //获得拦截器
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) { //循环遍历执行后置拦截
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
throws Exception {
HandlerInterceptor[] interceptors = getInterceptors(); //获得拦截器
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try { //循环遍历执行完成拦截
interceptor.afterCompletion(request, response, this.handler, ex);
}
catch (Throwable ex2) {
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。
4、比如:JS 中的事件冒泡,JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。