Notes
Search…
Chain of Responsibility

介绍

定义:Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. 将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
适用场景:一个请求的处理需要多个对象中的一个或几个协作处理。
优点:
  • 请求的发送者和接受者解耦。
  • 可以动态组合。
缺点:若责任链太长,则影响性能。

示例

方式 1

Handler 负责下一 Handler 的调用。
1
public abstract class Handler {
2
protected Handler successor = null;
3
4
public void setSuccessor(Handler successor) {
5
this.successor = successor;
6
}
7
8
public final void handle() {
9
boolean handled = doHandle();
10
if (successor != null && !handled) {
11
successor.handle();
12
}
13
}
14
15
protected abstract boolean doHandle();
16
}
17
18
public class HandlerA extends Handler {
19
@Override
20
protected boolean doHandle() {
21
boolean handled = false;
22
//...
23
return handled;
24
}
25
}
26
27
public class HandlerB extends Handler {
28
@Override
29
protected boolean doHandle() {
30
boolean handled = false;
31
//...
32
return handled;
33
}
34
}
35
36
public class HandlerChain {
37
private Handler head = null;
38
private Handler tail = null;
39
40
public void addHandler(Handler handler) {
41
handler.setSuccessor(null);
42
43
if (head == null) {
44
head = handler;
45
tail = handler;
46
return;
47
}
48
49
tail.setSuccessor(handler);
50
tail = handler;
51
}
52
53
public void handle() {
54
if (head != null) {
55
head.handle();
56
}
57
}
58
}
59
60
// 使用举例
61
public class Application {
62
public static void main(String[] args) {
63
HandlerChain chain = new HandlerChain();
64
chain.addHandler(new HandlerA());
65
chain.addHandler(new HandlerB());
66
chain.handle();
67
}
68
}
Copied!

方式 2

HandlerChain 负责下一 Handler 的调用。
1
2
public interface IHandler {
3
boolean handle();
4
}
5
6
public class HandlerA implements IHandler {
7
@Override
8
public boolean handle() {
9
boolean handled = false;
10
//...
11
return handled;
12
}
13
}
14
15
public class HandlerB implements IHandler {
16
@Override
17
public boolean handle() {
18
boolean handled = false;
19
//...
20
return handled;
21
}
22
}
23
24
public class HandlerChain {
25
private List<IHandler> handlers = new ArrayList<>();
26
27
public void addHandler(IHandler handler) {
28
this.handlers.add(handler);
29
}
30
31
public void handle() {
32
for (IHandler handler : handlers) {
33
boolean handled = handler.handle();
34
if (handled) {
35
break;
36
}
37
}
38
}
39
}
40
41
// 使用举例
42
public class Application {
43
public static void main(String[] args) {
44
HandlerChain chain = new HandlerChain();
45
chain.addHandler(new HandlerA());
46
chain.addHandler(new HandlerB());
47
chain.handle();
48
}
49
}
Copied!

源码

Servlet Filter

26 行的本质是递归调用,目的是为了可以实现双向拦截。
1
// javax.servlet
2
public interface Filter {
3
public void init(FilterConfig filterConfig) throws ServletException;
4
public void doFilter(ServletRequest request, ServletResponse response,
5
FilterChain chain) throws IOException, ServletException;
6
public void destroy();
7
}
8
9
public interface FilterChain {
10
public void doFilter(ServletRequest request, ServletResponse response)
11
throws IOException, ServletException;
12
}
13
14
// Tomcat 的实现
15
public final class ApplicationFilterChain implements FilterChain {
16
private int pos = 0; //当前执行到了哪个filter
17
private int n; //filter的个数
18
private ApplicationFilterConfig[] filters;
19
private Servlet servlet;
20
21
@Override
22
public void doFilter(ServletRequest request, ServletResponse response) {
23
if (pos < n) {
24
ApplicationFilterConfig filterConfig = filters[pos++];
25
Filter filter = filterConfig.getFilter();
26
filter.doFilter(request, response, this);
27
} else {
28
// filter都处理完毕后,执行servlet
29
servlet.service(request, response);
30
}
31
}
32
33
public void addFilter(ApplicationFilterConfig filterConfig) {
34
for (ApplicationFilterConfig filter:filters)
35
if (filter==filterConfig)
36
return;
37
38
if (n == filters.length) {//扩容
39
ApplicationFilterConfig[] newFilters = new ApplicationFilterConfig[n + INCREMENT];
40
System.arraycopy(filters, 0, newFilters, 0, n);
41
filters = newFilters;
42
}
43
filters[n++] = filterConfig;
44
}
45
}
46
47
// Spring 的 mock 实现,org.springframework.mock.web
48
public class MockFilterChain implements FilterChain {
49
private final List<Filter> filters;
50
51
@Override
52
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
53
Assert.notNull(request, "Request must not be null");
54
Assert.notNull(response, "Response must not be null");
55
56
if (this.request != null) {
57
throw new IllegalStateException("This FilterChain has already been called!");
58
}
59
60
if (this.iterator == null) {
61
this.iterator = this.filters.iterator();
62
}
63
64
if (this.iterator.hasNext()) {
65
Filter nextFilter = this.iterator.next();
66
nextFilter.doFilter(request, response, this);
67
}
68
69
this.request = request;
70
this.response = response;
71
}
72
}
Copied!
1
// ch.qos.logback.classic.selector.servlet
2
public class LoggerContextFilter implements Filter {
3
4
public void destroy() {
5
//do nothing
6
}
7
8
public void doFilter(ServletRequest request, ServletResponse response,
9
FilterChain chain) throws IOException, ServletException {
10
11
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
12
ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
13
ContextJNDISelector sel = null;
14
15
if (selector instanceof ContextJNDISelector) {
16
sel = (ContextJNDISelector)selector;
17
sel.setLocalContext(lc);
18
}
19
20
try {
21
chain.doFilter(request, response);
22
} finally {
23
if (sel != null) {
24
sel.removeLocalContext();
25
}
26
}
27
}
28
29
public void init(FilterConfig arg0) throws ServletException {
30
//do nothing
31
}
32
}
Copied!

Spring Interceptor

DispatcherServlet 的 doDispatch() 在真正的业务逻辑执行前后,执行 HandlerExecutionChain 中的 applyPreHandle() 和 applyPostHandle() 函数。
1
public class HandlerExecutionChain {
2
private final Object handler;
3
private HandlerInterceptor[] interceptors;
4
5
public void addInterceptor(HandlerInterceptor interceptor) {
6
initInterceptorList().add(interceptor);
7
}
8
9
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
10
HandlerInterceptor[] interceptors = getInterceptors();
11
if (!ObjectUtils.isEmpty(interceptors)) {
12
for (int i = 0; i < interceptors.length; i++) {
13
HandlerInterceptor interceptor = interceptors[i];
14
if (!interceptor.preHandle(request, response, this.handler)) {
15
triggerAfterCompletion(request, response, null);
16
return false;
17
}
18
}
19
}
20
return true;
21
}
22
23
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
24
HandlerInterceptor[] interceptors = getInterceptors();
25
if (!ObjectUtils.isEmpty(interceptors)) {
26
for (int i = interceptors.length - 1; i >= 0; i--) {
27
HandlerInterceptor interceptor = interceptors[i];
28
interceptor.postHandle(request, response, this.handler, mv);
29
}
30
}
31
}
32
33
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)
34
throws Exception {
35
HandlerInterceptor[] interceptors = getInterceptors();
36
if (!ObjectUtils.isEmpty(interceptors)) {
37
for (int i = this.interceptorIndex; i >= 0; i--) {
38
HandlerInterceptor interceptor = interceptors[i];
39
try {
40
interceptor.afterCompletion(request, response, this.handler, ex);
41
} catch (Throwable ex2) {
42
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
43
}
44
}
45
}
46
}
47
}
Copied!
Last modified 1yr ago