设计模式《JAVA与模式》之责任链模式
在阎宏博士的《JAVA与模式》一书中开头是这样描述责任链(Chain of Responsibility)模式的:
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
从击鼓传花谈起
击鼓传花是一种热闹而又紧张的饮酒游戏。在酒宴上宾客依次坐定位置,由一人击鼓,击鼓的地方与传花的地方是分开的,以示公正。开始击鼓时,花束就开始依次传递,鼓声一落,如果花束在某人手中,则该人就得饮酒。
比如说,贾母、贾赦、贾政、贾宝玉和贾环是五个参加击鼓传花游戏的传花者,他们组成一个环链。击鼓者将花传给贾母,开始传花游戏。花由贾母传给贾赦,由贾赦传给贾政,由贾政传给贾宝玉,又贾宝玉传给贾环,由贾环传回给贾母,如此往复,如下图所示。当鼓声停止时,手中有花的人就得执行酒令。
击鼓传花便是责任链模式的应用。责任链可能是一条直线、一个环链或者一个树结构的一部分。
责任链模式的结构
下面使用了一个责任链模式的最简单的实现。
责任链模式涉及到的角色如下所示:
● 抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义
出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
● 具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
源代码
抽象处理者角色
public abstract class Handler { /**
* 持有后继的责任对象
*/
protected Handler successor;
/**
* 示意处理请求的方法,虽然这个示意方法是没有传入参数的
* 但实际是可以传入参数的,根据具体需要来选择是否传递参数
*/
public abstract void handleRequest();
/**
* 取值方法
*/
public Handler getSuccessor() {
return successor;
}
/**
* 赋值方法,设置后继的责任对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
} }
具体处理者角色
public class ConcreteHandler extends Handler {
/**
* 处理方法,调用此方法处理请求
*/
@Override
public void handleRequest() {
/**
* 判断是否有后继的责任对象
* 如果有,就转发请求给后继的责任对象
* 如果没有,则处理请求
*/
if(getSuccessor() != null)
{
System.out.println("放过请求");
getSuccessor().handleRequest();
}else
{
System.out.println("处理请求");
}
} }
客户端类
public class Client { public static void main(String[] args) {
//组装责任链
Handler handler1 = new ConcreteHandler();
Handler handler2 = new ConcreteHandler();
handler1.setSuccessor(handler2);
//提交请求
handler1.handleRequest();
} }
可以看出,客户端创建了两个处理者对象,并指定第一个处理者对象的下家是第二个处理者对象,而第二个处理者对象没有下家。然后客户端将请求传递给第一个处理者对象。
由于本示例的传递逻辑非常简单:只要有下家,就传给下家处理;如果没有下家,就自行处理。因此,第一个处理者对象接到请求后,会将请求传递给第二个处理者对象。由于第二个处理者对象没有下家,于是自行处理请求。活动时序图如下所示。
使用场景
来考虑这样一个功能:申请聚餐费用的管理。
很多公司都是这样的福利,就是项目组或者是部门可以向公司申请一些聚餐费用,用于组织项目组成员或者是部门成员进行聚餐活动。
申请聚餐费用的大致流程一般是:由申请人先填写申请单,然后交给领导审批,如果申请批准下来,领导会通知申请人审批通过,然后申请人去财务领取费用,如果没有批准下来,领导会通知申请人审批未通过,此事也就此作罢。
不同级别的领导,对于审批的额度是不一样的,比如,项目经理只能审批500元以内的申请;部门经理能审批1000元以内的申请;而总经理可以审核任意额度的申请。
也就是说,当某人提出聚餐费用申请的请求后,该请求会经由项目经理、部门经理、总经理之中的某一位领导来进行相应的处理,但是提出申请的人并不知道最终会由谁来处理他的请求,一般申请人是把自己的申请提交给项目经理,或许最后是由总经理来处理他的请求。
可以使用责任链模式来实现上述功能:当某人提出聚餐费用申请的请求后,该请求会在 项目经理—〉部门经理—〉总经理 这样一条领导处理链上进行传递,发出请求的人并不知道谁会来处理他的请求,每个领导会根据自己的职责范围,来判断是处理请求还是把请求交给更高级别的领导,只要有领导处理了,传递就结束了。
需要把每位领导的处理独立出来,实现成单独的职责处理对象,然后为它们提供一个公共的、抽象的父职责对象,这样就可以在客户端来动态地组合职责链,实现不同的功能要求了。
源代码
抽象处理者角色类
public abstract class Handler {
/**
* 持有下一个处理请求的对象
*/
protected Handler successor = null;
/**
* 取值方法
*/
public Handler getSuccessor() {
return successor;
}
/**
* 设置下一个处理请求的对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
/**
* 处理聚餐费用的申请
* @param user 申请人
* @param fee 申请的钱数
* @return 成功或失败的具体通知
*/
public abstract String handleFeeRequest(String user , double fee);
}
具体处理者角色
public class ProjectManager extends Handler { @Override
public String handleFeeRequest(String user, double fee) { String str = "";
//项目经理权限比较小,只能在500以内
if(fee < 500)
{
//为了测试,简单点,只同意张三的请求
if("张三".equals(user))
{
str = "成功:项目经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}else
{
//其他人一律不同意
str = "失败:项目经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}
}else
{
//超过500,继续传递给级别更高的人处理
if(getSuccessor() != null)
{
return getSuccessor().handleFeeRequest(user, fee);
}
}
return str;
} }
public class DeptManager extends Handler { @Override
public String handleFeeRequest(String user, double fee) { String str = "";
//部门经理的权限只能在1000以内
if(fee < 1000)
{
//为了测试,简单点,只同意张三的请求
if("张三".equals(user))
{
str = "成功:部门经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}else
{
//其他人一律不同意
str = "失败:部门经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}
}else
{
//超过1000,继续传递给级别更高的人处理
if(getSuccessor() != null)
{
return getSuccessor().handleFeeRequest(user, fee);
}
}
return str;
} }
public class GeneralManager extends Handler { @Override
public String handleFeeRequest(String user, double fee) { String str = "";
//总经理的权限很大,只要请求到了这里,他都可以处理
if(fee >= 1000)
{
//为了测试,简单点,只同意张三的请求
if("张三".equals(user))
{
str = "成功:总经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}else
{
//其他人一律不同意
str = "失败:总经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}
}else
{
//如果还有后继的处理对象,继续传递
if(getSuccessor() != null)
{
return getSuccessor().handleFeeRequest(user, fee);
}
}
return str;
} }
客户端类
public class Client { public static void main(String[] args) {
//先要组装责任链
Handler h1 = new GeneralManager();
Handler h2 = new DeptManager();
Handler h3 = new ProjectManager();
h3.setSuccessor(h2);
h2.setSuccessor(h1); //开始测试
String test1 = h3.handleFeeRequest("张三", 300);
System.out.println("test1 = " + test1);
String test2 = h3.handleFeeRequest("李四", 300);
System.out.println("test2 = " + test2);
System.out.println("---------------------------------------"); String test3 = h3.handleFeeRequest("张三", 700);
System.out.println("test3 = " + test3);
String test4 = h3.handleFeeRequest("李四", 700);
System.out.println("test4 = " + test4);
System.out.println("---------------------------------------"); String test5 = h3.handleFeeRequest("张三", 1500);
System.out.println("test5 = " + test5);
String test6 = h3.handleFeeRequest("李四", 1500);
System.out.println("test6 = " + test6);
} }
运行结果如下所示:
aaarticlea/png;base64,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" alt="" />
纯的与不纯的责任链模式
一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又 把责任向下传的情况。
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。
纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。有些人认为不纯的责任链根本不是责任链模式,这也许是有道理的。但是在实际的系统里,纯的责任链很难找到。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。
责任链模式在Tomcat中的应用
众所周知Tomcat中的Filter就是使用了责任链模式,创建一个Filter除了要在web.xml文件中做相应配置外,还需要实现javax.servlet.Filter接口。
public class TestFilter implements Filter{ public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException { chain.doFilter(request, response);
} public void destroy() {
} public void init(FilterConfig filterConfig) throws ServletException {
} }
使用DEBUG模式所看到的结果如下
其实在真正执行到TestFilter类之前,会经过很多Tomcat内部的类。顺带提一下其实Tomcat的容器设置也是责任链模式,注意被红色方框所圈中的类,从Engine到Host再到Context一直到Wrapper都是通过一个链传递请求。被绿色方框所圈中的地方有一个名为ApplicationFilterChain的类,ApplicationFilterChain类所扮演的就是抽象处理者角色,而具体处理者角色由各个Filter扮演。
第一个疑问是ApplicationFilterChain将所有的Filter存放在哪里?
答案是保存在ApplicationFilterChain类中的一个ApplicationFilterConfig对象的数组中。
/**
* Filters.
*/
private ApplicationFilterConfig[] filters =
new ApplicationFilterConfig[0];
那ApplicationFilterConfig对象又是什么呢?
ApplicationFilterConfig是一个Filter容器。以下是ApplicationFilterConfig类的声明:
/**
* Implementation of a <code>javax.servlet.FilterConfig</code> useful in
* managing the filter instances instantiated when a web application
* is first started.
*
* @author Craig R. McClanahan
* @version $Id: ApplicationFilterConfig.java 1201569 2011-11-14 01:36:07Z kkolinko $
*/
当一个web应用首次启动时ApplicationFilterConfig会自动实例化,它会从该web应用的web.xml文件中读取配置的Filter的信息,然后装进该容器。
刚刚看到在ApplicationFilterChain类中所创建的ApplicationFilterConfig数组长度为零,那它是在什么时候被重新赋值的呢?
private ApplicationFilterConfig[] filters =
new ApplicationFilterConfig[0];
是在调用ApplicationFilterChain类的addFilter()方法时。
/**
* The int which gives the current number of filters in the chain.
*/
private int n = 0;
public static final int INCREMENT = 10;
void addFilter(ApplicationFilterConfig filterConfig) { // Prevent the same filter being added multiple times
for(ApplicationFilterConfig filter:filters)
if(filter==filterConfig)
return; if (n == filters.length) {
ApplicationFilterConfig[] newFilters =
new ApplicationFilterConfig[n + INCREMENT];
System.arraycopy(filters, 0, newFilters, 0, n);
filters = newFilters;
}
filters[n++] = filterConfig; }
变量n用来记录当前过滤器链里面拥有的过滤器数目,默认情况下n等于0,ApplicationFilterConfig对象数组的长度也等于0,所以当第一次调用addFilter()方法时,if (n == filters.length)的条件成立,ApplicationFilterConfig数组长度被改变。之后filters[n++] = filterConfig;将变量filterConfig放入ApplicationFilterConfig数组中并将当前过滤器链里面拥有的过滤器数目+1。
那ApplicationFilterChain的addFilter()方法又是在什么地方被调用的呢?
是在ApplicationFilterFactory类的createFilterChain()方法中。
1 public ApplicationFilterChain createFilterChain
2 (ServletRequest request, Wrapper wrapper, Servlet servlet) {
3
4 // get the dispatcher type
5 DispatcherType dispatcher = null;
6 if (request.getAttribute(DISPATCHER_TYPE_ATTR) != null) {
7 dispatcher = (DispatcherType) request.getAttribute(DISPATCHER_TYPE_ATTR);
8 }
9 String requestPath = null;
10 Object attribute = request.getAttribute(DISPATCHER_REQUEST_PATH_ATTR);
11
12 if (attribute != null){
13 requestPath = attribute.toString();
14 }
15
16 // If there is no servlet to execute, return null
17 if (servlet == null)
18 return (null);
19
20 boolean comet = false;
21
22 // Create and initialize a filter chain object
23 ApplicationFilterChain filterChain = null;
24 if (request instanceof Request) {
25 Request req = (Request) request;
26 comet = req.isComet();
27 if (Globals.IS_SECURITY_ENABLED) {
28 // Security: Do not recycle
29 filterChain = new ApplicationFilterChain();
30 if (comet) {
31 req.setFilterChain(filterChain);
32 }
33 } else {
34 filterChain = (ApplicationFilterChain) req.getFilterChain();
35 if (filterChain == null) {
36 filterChain = new ApplicationFilterChain();
37 req.setFilterChain(filterChain);
38 }
39 }
40 } else {
41 // Request dispatcher in use
42 filterChain = new ApplicationFilterChain();
43 }
44
45 filterChain.setServlet(servlet);
46
47 filterChain.setSupport
48 (((StandardWrapper)wrapper).getInstanceSupport());
49
50 // Acquire the filter mappings for this Context
51 StandardContext context = (StandardContext) wrapper.getParent();
52 FilterMap filterMaps[] = context.findFilterMaps();
53
54 // If there are no filter mappings, we are done
55 if ((filterMaps == null) || (filterMaps.length == 0))
56 return (filterChain);
57
58 // Acquire the information we will need to match filter mappings
59 String servletName = wrapper.getName();
60
61 // Add the relevant path-mapped filters to this filter chain
62 for (int i = 0; i < filterMaps.length; i++) {
63 if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
64 continue;
65 }
66 if (!matchFiltersURL(filterMaps[i], requestPath))
67 continue;
68 ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
69 context.findFilterConfig(filterMaps[i].getFilterName());
70 if (filterConfig == null) {
71 // FIXME - log configuration problem
72 continue;
73 }
74 boolean isCometFilter = false;
75 if (comet) {
76 try {
77 isCometFilter = filterConfig.getFilter() instanceof CometFilter;
78 } catch (Exception e) {
79 // Note: The try catch is there because getFilter has a lot of
80 // declared exceptions. However, the filter is allocated much
81 // earlier
82 Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
83 ExceptionUtils.handleThrowable(t);
84 }
85 if (isCometFilter) {
86 filterChain.addFilter(filterConfig);
87 }
88 } else {
89 filterChain.addFilter(filterConfig);
90 }
91 }
92
93 // Add filters that match on servlet name second
94 for (int i = 0; i < filterMaps.length; i++) {
95 if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
96 continue;
97 }
98 if (!matchFiltersServlet(filterMaps[i], servletName))
99 continue;
100 ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
101 context.findFilterConfig(filterMaps[i].getFilterName());
102 if (filterConfig == null) {
103 // FIXME - log configuration problem
104 continue;
105 }
106 boolean isCometFilter = false;
107 if (comet) {
108 try {
109 isCometFilter = filterConfig.getFilter() instanceof CometFilter;
110 } catch (Exception e) {
111 // Note: The try catch is there because getFilter has a lot of
112 // declared exceptions. However, the filter is allocated much
113 // earlier
114 }
115 if (isCometFilter) {
116 filterChain.addFilter(filterConfig);
117 }
118 } else {
119 filterChain.addFilter(filterConfig);
120 }
121 }
122
123 // Return the completed filter chain
124 return (filterChain);
125
126 }
可以将如上代码分为两段,51行之前为第一段,51行之后为第二段。
第一段的主要目的是创建ApplicationFilterChain对象以及一些参数设置。
第二段的主要目的是从上下文中获取所有Filter信息,之后使用for循环遍历并调用filterChain.addFilter(filterConfig);将filterConfig放入ApplicationFilterChain对象的ApplicationFilterConfig数组中。
那ApplicationFilterFactory类的createFilterChain()方法又是在什么地方被调用的呢?
是在StandardWrapperValue类的invoke()方法中被调用的。
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAiYAAABzCAIAAAAjcF58AAAgAElEQVR4nO1d768exXWe/6B/QNpGqVJSKR/Ite810n7wx1apon6h2DH4GrtSN5GiqFUqFRkEhNh1HBSiTRslhTo1agBbjpuiAhsgBUOSoguES0MQctiaiwM1vvgnECCR7Uw/7K9zZs6Zmd13d9937z2PRtb7zjtz5pwzZ+aZmfWdVVogEAgEgkGgOpFy4HPXXXvN1Qc+d10n0mYJaayiJJuW7D5az5JIxSmZ3Zulgp7QKED8hZnYaI8uBA4RmWmcqzmVUTALQ6/WoXRFb5iUcr74mY9/8TMfv/aaq7U+eO01V+dfmbJZEimAfg1rijRWJuJ0KpRTaNJX691RDuhPILByJJAWXnJgpDFUqVCIUQc4rg6WKQdxR5RTmiaU00VbOKiMWY+Ir+BGmTmqBbBSUZJNTDkwuNxR2QHlHDu4Wa/syNOxg5vdlFNbgztmZmB4fDqUU2pAloBubDGku5pW0rjqvjpeweipfw8vOSSyJFIqimPDG1yHZ0lEqJsl0VRDuBPKqU2bScrpsgmucFdLeyaovO03QzttA+eNSnhTXeswwp9NmJRz7Nix/fv3BzaSn6fplR333PWla6+5+p67vqRXdvAnbJYNAwRkYwjlBIJa1iDZ1ZfwksPDatrbKa7RNDi6oBwQb0I5/arUkTtmk3KwXryOiHKeeOKJT37yk1dddVVgE9dec7U+tlkf23ztNVfrSxfRVwK2DSDHc/ZSDZY0VlGSFoWLwydzuwo3oNAHUZLYhQ1QlFPWgrrGaRrXgmw9/RZxepiUg1oH1aMoQnKAVq49N1MMdQ7pQEpQ2W7tBmwq3tH4S1LOQK7KkqhSCWw3KP/TmaQ3cINEacgz1KaMGc5WCDj6iAl1ImK5EPI4gXGEsTgl1Wsd8JYv6uM7jxMoGbZD4HAg12ZQlqMwPFjj2nI4mWiYITaqkr9RW44hntAKW2/Y7lj958JtX9lNWFERts+pKSfnm89+9rPhlPO/z/7kx48+ok8//rNnHit2Occ2N9jl1DlZEtsjGvYQXDKXFuZOMCk5jc1hWOeDwlyH2pRj16pHT1nG1pOzCM/rfsqhW6dWK1gr9rSKKeZ3ICdK0bSF/BJe0vCE7dgyt/6RjZOADUAg5VgMaUyVZJ8QMw/XR3yom73PhRArwRdv0DROvdYBX/6K2nY4gQo8HJnO4YBd7dCHc4KnLTogiabJnxwHm5POUZZWTOzhuYLkIHKXw/R4hEdB2DanoJyKb7Zt2+agnJce//yTBz7x5IFPHPjqX7z6zN788+Fky4dvLa8c3LxycHODZzlFDr9IwuszsK4hH1OVn81+JY93HIcj7u6kopzWk7EINus/6PC27tgs45mr1ospRvrJJccglNL5BJE0Kom7mnZs/gP+ZhQjfGvoTzqN6RQqXorOtYenMYO4moMzsjvUSw24EApxgt80LoTaBnxeMTZWLbwTyMCzFhtYb9f5D7PLtAsyuxzb+YzhdrNWK7yeHgN5batvdPA4Ys+7y8Fl6Cbc8zmrv9KYb9yU8/h3/vh3v33zyoe//PrffOyZI5/JP99905+8/MJzKwc3h/yPNXp4Z0lUuYed+4w6zGcicMkVSqeUw2zqPRYNRDmEZg0px7cDIXYeQHJ4SWcT+AdMOXYxtq6BVrscrIm5qDRF5vOek+/9oR5AOV4n+E0LppzAgC9yI7xgD6ccY2ZrQjm8PhNRTrugcrTsbZQAvV7jRFOx15xyiCZsk4J3Ofv3778KYN++fbT+Wqff/KMrZx699MY/f+0LH/3J/X+ef/7231116pcvB/xdjr1WImaNLIngRhtYYPcK+dnanhdfeqMcUk+/RXBMcBo0phz6CwJTDK/NKQfaYqDzrbkJrSfCShKesAOgKA6kcnFSuzFhJ4pwygHdac++QBvo0sTsJq6PvKEOV05kCHmdwMWb0QqpXuuAhwsab6AygdeOctz6EKUDKIcJSAtEKz5emIBySK2Y2GtJObThDiEuim32n6T/866PXX7r8KUTe776+Y8+9W+fzj//098GPvsB21xzU1r/hP6HobUxDqAcjfeBkHV7ohxST8aiWrUoSdrtckrR1VynwHFs7P2LEaYYsol0ICXILlTnUnm+ko42rGnJmEmaysfRCP8jgqdTaHOqTNjdqelmvo88oQ4ilgsh0gnN4o1Tr3XAm9OWUnHqClQq8HwzMhwOpIqwR5jCgZTDOJn0i9nt/P5oUsqhtbJiz5orPJSDfcX0uLlc829yGlLOf3zto1fOppff+M7ev/6DJ/71z/LP3/wid5ImaAO+s9xwbN0FwXDs6oIOVdyYyT7qxrRG7c2eEwSTIgt5kKObUs6//8MfXnn3+ctnH977V7//X//yp/nn5AtCOV0itf4/VBhkJE+KwvPMYOnCvzPaR8OqNaNOEEwC7sTJRjPK+fH9Ow/d+pFDt37km7s//cIjt+aff/CPWydSVtANZCTPPqSPtDhhnaObaz0FAoFAIPBCKEcgEAgEA0EoRyAQCAQDQShHIBAIBANBKEcgEAgEA0EoRyAQCAQDQShHIBAIBANhOMr5vRsOeNNgyhSoL6Jo+yf/HEJvABxEmUkxa/rMCNaxW3qM1eCR475FxiW/uttm0EsXBDmGo5wtX398y12Pbbnrseu+XqQtVbqr+JesCO9dclxvFADrkrdpUk5fyuD7MidzWIFwfRzX6M0OxC1N0d/AAYPbfckdrRRbkpfSD+WksaIu3Btxn/eG4Shn+bW3vckpoF1wh91uSt+fOgHCKKd7ZerLjYxbhCecFxzVWQ+j62cHgtdj69MtE6KfWMXTtE7jRm8I8IG75qvzbVmWRMbdvfbvI+vvXjGiZzlCOUHN1tfAdrayajm3TuPkyeexdeqWCdFHrHLM2xXlcH7uyfus+cI4Bkb0LMeOFXgzO3mDO9i2B13ZbZQnm8jrpLEir0An99LkuwD6UAZOqI4h7RASxxF2ZpRk5qXksLrDw8bJBdFZtMec24Mm3U1iBG6x7okHmuAYcr2nI4l9YrlOsdFDrLLMgpQnz6rA3frgzn/LXmZ5wbynwK5um+A6i+OYpTsGXSsYwbOcEu432ag4JfvdHO3MVEAu1qgmCiF2dKG5DLzWBXxEpfpQBruIuJI6QEhdpCpQiWWrUx6GI42syHiMppwW3c1gxt3CGIU0qdslQwucWFWzJCGWVJtED7HqohxLeZ0lsbWUQjrYVbQ5HDTO9FTnuqYh5QjjWBjtsxy8PlZodQk72Xmw5h45dBNhsVV9NWOOnJI6UoZa1hWzBRhcPotKjW19/NXxOCYW06Ai5zFSXpvudmF23eI3qvzKhpYxXVaBqJhFPGyd9VbHsere5VCvXTH3OexyhK4O5AdUb+AcxkVs5nrHaJ/luJYPeXB6jmlwBjNyiCYmpxxbsa6UIZd1up7owixKyzc9l2XB3Oqpbix1nco3pZzG3e3FTLrFb5SDcsgVusleNbWFLsB7ilWyeUr5LInQ6VYg5YTvcijKabY7oQJPGIfCeJ/lGOvFIoyGfuM32onjgxTuYM0cOt0pAwdKBv83FiRAr5B83MUxMXS91ZEocA5BVmQ8BqplSaQcTXu6m8Lsu4UxCnuqbpcKLXrWtsSSanNe6zxW0SDJy1mTPUEAtfleyqFjIYxymK5pdLAmh2okxvssx95pF4WMrKIUPoEGEoyRA8uTTXCUA9s23jMPd+lo5ulYGewjUNxQ2CPEmOOQVMrnvIeBHKoi57GqLPqvp027m2Gf2XeLZVSWRCqOyb8mIkOLnoJtXxGt007rJVYZ9Unla3F1SHgph97zB1IO5xybRGBAeQsLxvQsRxCArMP/BDwsOl8TcqeM48OABzRrymkjHQlrHCN6liMIwlgPkLumnGyyv/OcJQzXpWvGaXKoNbMQyhHMBmSSYDHWVYRAYEMoRyAQCAQDQShHIBAIBANBKEcgEAgEA0EoRyAQCAQDQShHIBAIBANBKEcgEAgEA0EoRyAQCAQDYUR3rE0OeNdF278B6eoeC3Q5W7d/dBH8Fy6Btkzt6o5OPdOjwyfErOkzI1hXbuliahoJRnTHmnHDVQtMkXLwRUzRCN4e37hY90BXRtq3WDnRl8PBn2USl5a1Qrg+llGTNNsXxC0s+JHZA+WQtxqCn6j3WAzB8eO5Yy1Loiia7K+wW881k//5t0MCeRdvGNJe3x4fiP7+Np7xjGF1Y60mcDi+JBNcWNlfWLI3UqO7jgeC12Pr0y3h4G5+6+GoA15Val7hHUU1s9XdNIzrRvMsJ++ryXpmjVEOFyFrnXKC2uyFctC1yZ35uOXcOo2TJ5/H1qlbmsB9v3UvyIw33UXce8AHmTnG8iwno16dlIcafYE9lW/fW67xBfr1S1pARXByZV6Jz18db75K3Xv9O26FVAzaxUaNqUDYTfWkzqSqRrHmanNtEecADm6AOe3eDdFC8wy//ovje4eQOAbnJuUhCpxujOqGkuY8S52N0Jn1D87tgSEB94ntMdr8GXeLFWjcdKGbDHDPayjMKZ/wD/VKBWJIkvOVmyjwWzb4k5Bh1qojeZZTO8N4uYVCExQ6+rfzyX41vEy9ZR3GNFcXtUK9vH2Ub48nTCZNa6B2uHpBlMP1Qg8ON5aixdiHejXqNWgCmGWo6nA+pWZ9siKa/Ws30ZRDSSC2NAH7whl3C2MUM10ED3BCLKm2NqNI40zPWOMscjEFqEP3d+W/YTaH43iWAx1EehB/5fKtfmVmbWYdZAlDdckfsqT1a6cxiLh273LsV07ZdrEzjoNynKaFqB2unodyyNUaFwNdOJxanxY6g1ki1HxbH391PCERi2lQ0fBM9ZWURzed50IpAZQz427xG1V+bTbALbF065oOI26XY7TCymQBHcKtsFDhtXSwNgEsT9MzUReUkyXEW9ZDKYdcibSlHKLvHXO34S5LAdKuPiinmdpO9RyUU8lge6Enh5PzbTmug4QUpYCXwdzqqW5MGk7lm1IOO9fk9MF41YWZdIvfKAflOAa4Jda1Igzc5VCU04QSEAGjvSCeR1GN3jlnDM9ysOeMgyG8u66nEiqf3r1WwZrgtaEh0KQce99dfOmCcszlGj3zwok6L2cFJhGstV3u+K427OGUE6R2sHoc5SDHc73Qh8OxlsR+M6jXdJZEURyjx0LkGt2ujkRV/cNUNBe4YIIFPnI0nSWJ2a6PcmbfLYxRzHQRPMAJsaTanAvDKIexiHs9toM90ECBqq2lXU7rZzkm49Q5WRKR74Tn8u1+hdwP6CrftFZvWa9yo+D/PtCGckArSBF6aPEqsAqYdnVDOU3VDlYPcwN/mkD2Qi8OhwtUqBO5lOR7Dc1xSCpRHSpJrMdtD2FuLl2WGKRuRjgpIbXGEDMQDNtm2i2WUdx0oZsMcMJXbKcQbgukHEomSRTmwRAxZqB0yva+MI5nOQy4NZdvLSYQtENGncOPAp0fmXCnjOPDkNPFeAOoM4ziWQ4HoRzB0BhrbHVNOdlkf+c5SxiuS4d4VDLzEMoRCNYBZLZjIdPFoBg15QgEAoFgTBDKEQgEAsFAEMoRCAQCwUAQyhEIBALBQBDKEQgEAsFAEMoRCAQCwUAQyhEIBALBQBjDHWudAd4q0faPFLq6h6iW0/mfcQf/CUY7W1r8hUePxk6IWdNnRrCu3NLFtCAIxgjuWCthXMHUAlOkHOuWsM5mYXCbEnHHmlepPiinL2PB3+wRN1q1Qrg+7nveZgTiFhZ82PZAOdy1ZWlsdU3VZTPsu04xnjvWsvyN3RPOzu2qT/73yQ4JzH3JITAimLhJugeEUU73xuIbFMGNj/2FBHtdsX3VbP/wemx9uiUc3P1mPRwzoCszwQ2j6CJVzV97vZYxmmc5WfnK7gm6ZY1RDheka5Ny0P3PndnXcm6dxsmTz2Pr1C1N4L7FuRdk9gt18AXb/N3naxRjeZaTUS8pyjuJvmGdyqdeXoBueId38VcVwclV+MsLzJeWe+/Sx62QikG7cvpl3wFVK+C6St24KZ140TqUSZ6ftHtxQHNj0dB1cK1DSByDc5NyeQmnG6O6oaQ5z6L3FNmOIT3m3B4YEnB32R6jzZ9xt1gxyA1V3WRwed5RgCYMwnvMiwOI4UDOFW6eN/jMxdDr5Bq8kTzLqXvDftEDIBS4hyXyydgyujlLYntmA4HC1UWt2C8tR0feeKiSC3/TzEpv6nXxtrMoBWy7sC1WFSQQDWXAE5QHejDWHp3GBNXMY1WBSixbHc6n1KxPVmQ8RlMOJYFY8gasgmfcLYxRzFANHlyEWFJtbUaRxpme4cBZ5KIJa4y69jVCOR1jkmc5sDPAZ6PLyCGhiYEEM6hOZtZiljBUl/wha/lWULxELkeztURy7HLslzvZdrGzHpZrNFR9ZT3Qg7HU+rQwB8wSHiGVxrY+/up4QiI3ulVFzmOkPLrpPJc/k+Exu27xG1V+bTa4LLF065oOI26XY7TCymRB7TpllzOOZzlWbxMrZc1PeU0oJ0sitGtuRDnkaqgt5RDRF7gqohQg7eqecno1lpxvy3EdJKQoBSwEc6unurFYdirflHLYmSanD8arLsykW/xGOSjHMbgssa7VWOAuh6KcJoRA8Y1lL5LZqH9HjDE8yzF7Dx0M4R1+PZ1R+fQOuhowCV6fGgJNyrH3/vTRX6tZ2FwykhSLeCQvZw0OYsDUdrnHGDpSwO7kDtYsru7OWGwAMWqDPKazJIriGD0WItfodnXrSAQ4warIeAxUw2FpSciSxGzXNyXNvlsYo5ihGjy4CLGk2pwLwyiHsYg6WKNzKQ28C681iBE8y7HXC2VOlkTkS8u5fDu2qmMItHMqNs7gPzQWuVHwfx9oQzmgFaQIPbx5FVgFTLtCKQe2EiVJjCcD2wO9GAsXqKA4KBPkMTTHIalEdagkMVlYIYMFUx6ryqL/LktJSK34ZYLQsG2m3WIZxQ1V3WRwEb5iO4VwWyDlUDJJcjEPZawQNyXYtq9ljONZDgNu3bdetqjrCxn5343GgM4XsNwp4/gw5FAdbwCtKYziWQ4HoZz1hbH2a9eUk032d56zhOG6dN0cXM06hHIEgp4hsx0LGarrDqOmHIFAIBCMCUI5AoFAIBgIQjkCgUAgGAj9Us7lK7974qVz3/rhyb1HT0iSJElSV+lbPzz5xEvnLl/5Xa8zmKBz9Es5D//s7UeWz755/tK7v9GSJEmS1FV68/ylR5bPPvyzpn9ZIZgy+qWcOx987dz7V859oM++L0mSJEmdpXMf6HPvX7nzwdd6ncEEnaNfytl79MQ7v9Fnfi1JkiRJHad3fqP3Hj3R6wwm6By9U87FD/Xqe3r1vaA71vKSw6UfxGpTsjR83RlN6aKKD7Wo+PNkXkV7fj65AtmeTWrxB1P3gyQ7lbHRWV93kC5+KJQzPvROORc+1Kff1affDbpjLS9JpXSxvJto8ShXpnk6GqtNydJkdR/YpdSutMpf2h9BmcbXgZOhm0+fdFHFD7Ro6MVkXkVfeXFyhbOvbGrQv0v7I7UrzWvVmJ633XbNtoZFemCXmt+fUT+VsdFZX+eirEFNZT6wi/beBaGcEaJ3yjn/gT71rj71btAda3lJK6Xbldp+NP+c3bEpvq/4UGW2TUdjtSn57wnrIiHZHZuUUtEdLxbF7tul5vdnEyk5oYEqd1etHu+0dDsqPHxq0qcvJvOF21Gt+3YptSudMbWnrmEjW+roBanz2Ei3V6PmxWS+EE5msoPo/AdCOeND75Rz7n395sXJ0nKycVPyUzM/+/ImdcP3J5P8/VgRkhvWXU42qujLy3l+eoOKb9hZKZZ9eVP101RSeoMCXlpONqr4e67Cjl8HSA369HvIyaDW92O1M50xtaeuYZNEq9drbJDDpM783k618auZXfHc+0I540PvlHPm1/rkBX3yQtCznLykldLrlbr+iJlTYCF5+oI+uZxsLDPKkun1Krp9X3GR+MZ9GVG3qk5LyG5fUNcfSa+vi5F182L65AV98kisdqZP74vUzrSUGd9LinI3F5SP9CkNNBu6d6cqlLmga8VYj8X3XshuX6jd9fS+yLYdOFNjM22f+6Wpoi72ZK5eoS1pZnT7slULN8foTHVibQL+TEl4el99h/29digSqZmGWH5oACikMxH5lljGP8vJRsKQPDbcfc3IXE42qqqzuAFeqURk3rvTtlGfvKDP/FooZ3zonXJW39Mr5/XK+aBnOXlJIh0pXup+sM7MbltQ246Un29MnqpL5sXSbUqpG9OV83rlhWSDim57ocgsa+mDNyq1kFckJWS3LcBGubr6qX1R3tDBG9W2I3rlhWRD/tORuFDAFBXQnD8/3VYYBb1hNJTbXsvxeSw+mOdUbimqkG3ZTVA+p6WpDfuyFcrSbUfynKo5sulS1do/OaqSjopUJ9YmGOZYEmBJIhTJ1ERDRj4TAKQbqV4gxHJ9Cn0LC8cHvX3NWgStNtPBG4EVzsyn9kXVoFs5r1ffE8oZH3qnnNPv6RNn9YmzQc9y8pJcenJvpJRSO9ITZ/WJs9mtC2rbYetXpZSKv3tWnzibblPRrc/psnB063P6xOFYLSRPVjLxV0sCbsJR97lkw0LyZNVK+eG7O9SGvRmprb+5+iuTf9h8PfeGvRnVUJnzXLKhaMjhMey6qgrdVimqlkz5nJQGPWlYuiNWUE+y6cLhRnX93R1VeDAVuU6EzvFYnW5TStVm0p2LUxMN/fJBANBu5HoBi2X7tKoCUxkb7r52xwmVkEOcmSfMRvVpoZwRonfKOfWOfvVMhyndqtTWw/rVM9ktC/kH/eqzyZxSc3uz8nN8oCgZ3fJsXiu7ZSG65Vn96uFYLSQ/qqRVX2kJoIkzfN2irfjAs8lcmXNgh9p6uGzUFhXSXP2VyTf0MWvV6Ud7I7Ujzf91KpBuLT7oAzvU3N7sR3ujogzdFjSH97lfWlUyu2VBqYVorhbCNV2rik2uwoOp6AqAUmD12WV1dsuCUqpW2/A53yk+Df3yuQCo3Ej3gimWbR361spsNL586cAOVcekMxOoUZtz6h2hnPGhd8p586I+vqqPrwY9y8lLmmkpmVtMy6/pVhXdvKSPr2Y3z6uth/TxVX38UKzmk8dW9fFV/dieSKn4HlQyL5x/TreqstZqdvO8KirSEkATq3zdVX18Vd+zqLYuxnN7sqLwoVgtxlvrAlgU35wqLQ3Ih/roexZJnUsHqmhuvvKGw2P5B318KZmbj7fWVai2lpK53MNLyZzL57Q05KtCmVL5pWSubo4002ioLvDYnqiUxlWkOrGyxevhpeTmQ0a7lM9RaqIhI58LAMqNVC8QYkn/wN6EqYwNT18748TySa28KzPdWtp+zyIadG9eFMoZH3qnnDcu6ldW9SurQc9y8pJ2enRP/d7wLYdw5nzy6Gq2u/zP/HOL8ZyK717Vr6ymW1S0eykvnO2eLz8fql9Kv3tPrOaTR4sCtoRs93zdHF+3/gkUTrcopRbT8qshim9usX6N+92wLpGvX1lK5ky3WDpXzUFtWY+hRoH+VFtLyVzu4aXE43NbWu4f0tJDsEB8N22mvnuRMxm0RVXkOrGKMeAQtukCpUV1KNauMP0frqElnw8A2o10L9hqs/5BPVXJrPrC2deOOIECDxlHcNHuJSYTFkYxrN8QyhkheqecX53XL7+lX34r6FlOXnK9puymeXXd/eH56zs9k3xqPkknFHJ/rCYXYgjcnnZt7JABkN00H930zDBtTZp+dV4oZ3zonXJeP69fOiUpJGV/P6/+8r7w/PWeHr4jUtvTiYTcF6v55OFOVeqhp4YLgG9vV5+6IxugoU7S60I5I0TvlLNyXv/8lKSQVMwswfmSJk73xWo+eWjqaniSBACdVoRyRoh+KecbD71+/PTlX5zS//N/kiRJktRZ+sUpffz05W889HqvM5igc/RLOT9cPvPg8+eyt6/wfyUnSZIkSY1T9vaVB58/98gL8oq2kaFfyvntpSsPPf/2nQ++NvXX1kqSJGktpTsffO2h59/+7aUrvc5ggs7RL+UIBAKBQFBBKEcgEAgEA0EoRyAQCAQDQShHIBAIBANhOMoJuWNtMGUKpLGKkmz4ulNGGqs4bVEvS6JubM6SqJ0Ggr5RxkZnfS0QIAxHOSF3rPG10/qGqQ6nqi4pp9Zw+Nk0jc1GnTPGyCinLJ0lEbx/awbnw9nXsAAf+P1QThoTw8Ie07X/Zth3gskwHOWE3LHGVIUzapZE+ccuVspdUY4xotK4udQW5oAqJue4pbWlnM7QxNgsiQpvolo2y/YPr9pT1zActVsxOo+NLImUiuLYcB0x9IDDRnyEIPBgDM9y6NExO5TTydwyGeUYOniEjYlygK641hSMaEY503ezG7R6PSltuI4a0mgwcowoGD1G8SzHntPBKVYemeBIA8zCUZLE1kY9RTekVz8QEvJxksZ1Maqui7dgebj8NRSzzAE5wD64pYmNKsZOsG6N9kyc4qMT8MVsukYt1zbBL01hnYovuXrAMtw0nHqgWca5D6kz1VmmDLQncUaE3Uc2mmlo9QyIN+yv4EAixTL+oWd1eLDG9TUj03UWhyknS6JaJIgUpNxM87WgNUbyLKcIb+7sKEtieMZVDRU4lit+wAOxGi6EBDQdsnVZygHi/YoZWxZini1y6x+tYYxmLrdn4hS1U1Whm7aaoEygpZEeKAug38mm4aIbPimBHucqUp1FUw4lgZj0gnY5oRoy8tHCAHg7NJAIsVyfkhsaknLIcURaFEY58CAaaY7WHkI5axKjeJZToBjQIFRNCkKLO2NUGNOiNouwq066cP2Voxwzn5vWrbkQr87B7JX/wFECO5dRnsEuQhM12bTRIGkCJY2unyVRvk9j1vFV02gljmdBYgUPKnKdRVIObbXhbdvhNppo6JcPiLlBIFli2T4ltznMLsceR444cXrGFGkeURfikhbPQwVjwBie5SBUY9k8nLGW/k0ohxPfXAMAAAG+SURBVJYQRjkc5xAzBblCpCiH3zbxlFN8t0/VKM+gpuq5x3VI6KUcrzRkrIoi8+TJcc5j2gumdLJiU8pxnpVRWySPg/wa+uU7KMcRSJZYVzgF7nJ848gP4mDN2fOkboK1gDE8y8nK/6SmNT15gJgFu3N2DQinHHunAiQYUwBT1/iitS7+x5p1HkLMxBTlmEtkkx7og7UiI4qY0Yw9A+yI4riuQjVNHNowkx0ljfIA3JC5rWYP+oAfuIpUZxnuo/ckhdWJSU2NKMenISMfK80crDkCiRBLhxNjTRjluOPE5xmrG8xajRlNMB6M41kOPCM3j/aL85dyR17/b0xmWqzPBKIkQZOgJcEalHRd4yf836WJXFoxYA59FmZPlahK9ZN1CEN5BnvReUDZgHJsabQHTH7F9pjOYuZIY23g8D3qrKos+o+7TNNGVu1wer5upqElvzpvNE1pFEi22qx/CP4MpBxnnFg+gcD9TnhX+Y/pBCPGmJ7lCNYjyCcOTdH5srmXgx/vLqrbtmRiF0wBo3uWI1h36GAm7ppy0Flvl1IHohw5uRJMC0I5gnWAcUyxQ+5yBILpQChHIBAIBAPh/wEJLm5wI0j8DQAAAABJRU5ErkJggg==" alt="" />
由于invoke()方法较长,所以将很多地方省略。
public final void invoke(Request request, Response response)
throws IOException, ServletException {
...省略中间代码
// Create the filter chain for this request
ApplicationFilterFactory factory =
ApplicationFilterFactory.getInstance();
ApplicationFilterChain filterChain =
factory.createFilterChain(request, wrapper, servlet);
...省略中间代码
filterChain.doFilter(request.getRequest(), response.getResponse());
...省略中间代码
}
那正常的流程应该是这样的:
在StandardWrapperValue类的invoke()方法中调用ApplicationFilterChai类的createFilterChain()方法———>在ApplicationFilterChai类的createFilterChain()方法中调用ApplicationFilterChain类的addFilter()方法———>在ApplicationFilterChain类的addFilter()方法中给ApplicationFilterConfig数组赋值。
根据上面的代码可以看出StandardWrapperValue类的invoke()方法在执行完createFilterChain()方法后,会继续执行ApplicationFilterChain类的doFilter()方法,然后在doFilter()方法中会调用internalDoFilter()方法。
以下是internalDoFilter()方法的部分代码
// Call the next filter if there is one
if (pos < n) {
//拿到下一个Filter,将指针向下移动一位
//pos它来标识当前ApplicationFilterChain(当前过滤器链)执行到哪个过滤器
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = null;
try {
//获取当前指向的Filter的实例
filter = filterConfig.getFilter();
support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,
filter, request, response); if (request.isAsyncSupported() && "false".equalsIgnoreCase(
filterConfig.getFilterDef().getAsyncSupported())) {
request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,
Boolean.FALSE);
}
if( Globals.IS_SECURITY_ENABLED ) {
final ServletRequest req = request;
final ServletResponse res = response;
Principal principal =
((HttpServletRequest) req).getUserPrincipal(); Object[] args = new Object[]{req, res, this};
SecurityUtil.doAsPrivilege
("doFilter", filter, classType, args, principal); } else {
//调用Filter的doFilter()方法
filter.doFilter(request, response, this);
}
这里的filter.doFilter(request, response, this);就是调用我们前面创建的TestFilter中的doFilter()方法。而TestFilter中的doFilter()方法会继续调用chain.doFilter(request, response);方法,而这个chain其实就是ApplicationFilterChain,所以调用过程又回到了上面调用dofilter和调用internalDoFilter方法,这样执行直到里面的过滤器全部执行。
如果定义两个过滤器,则Debug结果如下:
设计模式《JAVA与模式》之责任链模式的更多相关文章
- 设计模式之jdk动态代理模式、责任链模式-java实现
设计模式之JDK动态代理模式.责任链模式 需求场景 当我们的代码中的类随着业务量的增大而不断增大仿佛没有尽头时,我们可以考虑使用动态代理设计模式,代理类的代码量被固定下来,不会随着业务量的增大而增大. ...
- java设计模式8.迭代子模式、责任链模式、命令模式
迭代子模式 迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象.它将迭代逻辑封装到一个独立的迭代子对象中,从而与聚集本身分开.迭代子对象是对遍历的抽象化,不同的聚集对象可以提供相同的迭代 ...
- 设计模式(13)--Chain of Responsibility(责任链模式)--行为型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一 ...
- 设计模式(C#)——12责任链模式
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 前言 在开发游戏过程中,当玩家合成一种道具的时候,对于不痛的道具,需要的碎片个数,类型是不同的.用传统的写法,就是 ...
- Delphi 设计模式:《HeadFirst设计模式》---行为模式之责任链模式
模式解说 责任链模式是一种对象的行为模式,它将处理客户端请求的那些对象联成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 通常使用在以下场合 1 有多个对象可以处理一个请求,哪个对象处理该请 ...
- Python的组合模式与责任链模式编程示例
Python的组合模式与责任链模式编程示例 这篇文章主要介绍了Python的组合模式与责任链模式编程示例,组合模式与责任链模式都属于Python的设计模式,需要的朋友可以参考下 组合模式 我们把Com ...
- Java设计模式(19)——行为模式之责任链模式(chain of responsibilitiy)
一.概述 概念 UML简图 角色 抽象处理器:定义处理请求的接口 具体处理器:接收到请求后可以选择处理,也可以选择发给下家处理(持有下家的引用) 当然这里必须指出,实际中纯的责任链模式很难寻找,一般是 ...
- python 设计模式之 (Chain of Responsibility)责任链模式
#写在前面 对于每一种设计模式,如果不理解它的原理和结构,是写不出例子来的.所以弄明白很重要. 等过完这段浑浑噩噩的日子,我要找个遍地开花的地方开怀大笑一场 #责任链模式定义 简书上一网友就把这个定义 ...
- 设计模式之二十:责任链模式(Chain of Responsibility)
感觉这个设计模式和组合模式一样是一种非常巧妙的设计模式,在须要使用它的地方假设不使用这样的设计模式代码会变的非常复杂,可是这样的设计模式的基本原理又是非常easy的. 责任链模式: 通过使多个对象都有 ...
- 【设计模式】行为型05责任链模式(Chain of responsibility Pattern)
学习地址:http://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html demo采用了DEBUG级别举例子,理解起 ...
随机推荐
- yum 安装报错:Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error"
[root@venn09 ~]# yum install -y vim Loaded plugins: fastestmirror Could not retrieve mirrorlist http ...
- 2019.01.17 bzoj2333: [SCOI2011]棘手的操作(启发式合并)
传送门 启发式合并菜题. 题意:支持与连通块有关的几种操作. 要求支持连边,单点修改,连通块修改,全局修改和单点查值,连通块查最大值和全局最大值. 我们对每个连通块和答案用可删堆维护最大值,然后用启发 ...
- express框架搭建服务端
1.管理员权限全局安装express npm i -g express-generator@4 2.创建express项目 express -e projectName 3.进入项目并安装 cd pr ...
- ip route 解释
[root@localhost ~]# ip route default via 172.16.0.1 dev ens192 proto static metric 100 172.16.0.0/16 ...
- 关于preg_match() / preg_replace()函数的一点小说明
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $ ...
- zl
https://mooc.study.163.com/course/2001281002?tid=2001392029&_trace_c_p_k2_=a1ef6cb9a64342008c8f5 ...
- innerText兼容处理
转载自:https://www.cnblogs.com/leejersey/p/3520497.html:稍微改了一下和加了一些注释: IE.Safari.Opera和Chrome支持innerTex ...
- Struts2-result
所有result-type <result-types> <result-type name="chain" class="com.opensympho ...
- GPS 编程笔记
1.在GPS系统内,经纬度的显示方式一般都可以根据自己的爱好选择,一般有"hddd.ddddd"(度.度),"hddd*mm.mmm"(度.分. 分),&quo ...
- MIT Molecular Biology 笔记6 转录的调控
视频 https://www.bilibili.com/video/av7973580?from=search&seid=16993146754254492690 教材 Molecular ...