学习是件开心事

责任链模式

责任链是一种行为模式。将处理请求的多个环节连在一起,形成一条链。
当请求的对象进入链条时,流过某个模块,某个模块就处理自身的逻辑,处理完成之后,将处理后的对象在交由下一个环节处理。以此来实现各个业务模块之间的解耦。拦截器链和过滤器链和tomcat的管道模式都是责任链的实现方式。

手动写一个责任链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// step1 先建立抽象的某一类的处理链节的处理器
public abstract class AbstractHandler {
/**
* 下一个模块
*/
public AbstractHandler abstractHandler;
public AbstractHandler getAbstractHandler() {
return abstractHandler;
}
public void setAbstractHandler(AbstractHandler abstractHandler) {
this.abstractHandler = abstractHandler;
}
abstract void execute(Person o);
public boolean hasNext() {
return this.abstractHandler != null;
}
}
// step2 具体的该类逻辑处理中的具体处理方案
// 一面
public class FirstAuditionHandler extends AbstractHandler {
@Override
void execute(Person o) {
//do something itself
o.setComments(o.getComments() + "基础好");
//hand to nextHandler
if (hasNext()) {
abstractHandler.execute(o);
}
}
}
// 二面
public class SecondAuditionHandler extends AbstractHandler {
@Override
void execute(Person o) {
//do something itself
o.setComments(o.getComments() + ",业务能力强");
//hand to nextHandler
if (hasNext()) {
abstractHandler.execute(o);
}
}
}
//终面
public class FinalAuditionHandler extends AbstractHandler {
@Override
void execute(Person o) {
//do something itself
o.setComments(o.getComments() + ",能加班");
//hand to nextHandler
if (hasNext()) {
abstractHandler.execute(o);
}
}
}
// step3 在调用的地方调用责任链,手动设置下一个handler
public class Person {
private String name;
private String comments = "";
}
public static void main(String[] args) {
Person o = new Person();
o.setName("面试人");
AbstractHandler firstAuditionHandler = new FirstAuditionHandler();
AbstractHandler secondAuditionHandler = new SecondAuditionHandler();
AbstractHandler finalAuditionHandler = new FinalAuditionHandler();
firstAuditionHandler.setAbstractHandler(secondAuditionHandler);
secondAuditionHandler.setAbstractHandler(finalAuditionHandler);
firstAuditionHandler.execute(o);
System.out.println(o.toString());
}

使用apache提供的责任链ChainBase

自己手写一个责任链虽然简单,但是需要在各个环节里指明下个环节。如果使用使用apache提供的责任链ChainBase,则可以省掉这部分代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// step1 定义所有环节
public class CommandAuditionChain extends ChainBase {
public CommandAuditionChain() {
addCommand(new FirstAuditionChain());
addCommand(new SecondAuditionChain());
addCommand(new FinalAuditionChain());
}
}
// step2 所有环节实现
// 一面
public class FirstAuditionChain implements Command {
@Override
public boolean execute(Context context) throws Exception {
//do something itself
Person o = (Person) context.get("面试人");
o.setComments(o.getComments() + "基础好");
context.put("面试人", o);
return false;
}
}
//二面
public class SecondAuditionChain implements Command {
@Override
public boolean execute(Context context) throws Exception {
//do something itself
Person o = (Person) context.get("面试人");
o.setComments(o.getComments() + ",业务能力强");
context.put("面试人", o);
return false;
}
}
// 终面
public class FinalAuditionChain implements Command {
@Override
public boolean execute(Context context) throws Exception {
//do something itself
Person o = (Person) context.get("面试人");
o.setComments(o.getComments() + ",能加班");
context.put("面试人", o);
return false;
}
}
// step3 测试 不用再指明环节关系了 因为已经定义好了
public static void main(String[] args) throws Exception {
CommandAuditionChain commandChain = new CommandAuditionChain();
Context context = new ContextBase();
Person o = new Person();
o.setName("面试人");
context.put("面试人", o);
commandChain.execute(context);
System.out.println(context.get("面试人").toString());
}

过滤器 (filter)

过滤器依赖于servlet容器。在实现上,基于函数回调。它可以对几乎所有请求进行过滤(不能过滤转发请求)。
应用场景:过滤请求的特殊字符,防止SQL注入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//step1 创建多个filter
public class Filter1 implements javax.servlet.Filter, Ordered {
public void init(FilterConfig filterConfig) {}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("==== filter1 doFilter LOWEST ====" + servletRequest.getLocalAddr());
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
System.out.println("==== filter1 destroy LOWEST ====");
}
//最低优先级
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
public class Filter2 implements javax.servlet.Filter, Ordered {
public void init(FilterConfig filterConfig) {}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("==== filter2 doFilter 0 ====" + servletRequest.getLocalName());
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
System.out.println("==== filter2 destroy 0 ====");
}
//优先级为0
public int getOrder() {
return 0;
}
}
public class Filter3 implements javax.servlet.Filter, Ordered {
public void init(FilterConfig filterConfig) {}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("==== filter3 doFilter HIGHEST ====" + servletRequest.getRemoteAddr());
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
System.out.println("==== filter3 destroy HIGHEST ====");
}
//优先级为最高
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
//step2 配置类
@Configuration
public class FilterConfiguration {
@Bean
public FilterRegistrationBean Filter1() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new Filter1());
registration.addUrlPatterns("/*");
registration.setName("Filter1");
registration.setOrder(Integer.MAX_VALUE);
Map<String, String> initParameters = new HashMap();
registration.setInitParameters(initParameters);
return registration;
}
@Bean
public FilterRegistrationBean Filter2() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new Filter2());
registration.addUrlPatterns("/*");
registration.setName("Filter2");
registration.setOrder(0);
Map<String, String> initParameters = new HashMap();
registration.setInitParameters(initParameters);
return registration;
}
@Bean
public FilterRegistrationBean Filter3() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new Filter3());
registration.addUrlPatterns("/*");
registration.setName("Filter3");
registration.setOrder(Integer.MIN_VALUE);
Map<String, String> initParameters = new HashMap();
registration.setInitParameters(initParameters);
return registration;
}
}

多个 Filter 执行顺序为:
根据优先级顺序由高到低执行 doFilter 方法


拦截器 (Interceptor)

拦截器是基于web框架的,在Spring中是依赖于SpringMVC框架。基于Java的反射机制,属于面向切面编程(AOP)的一种运用。
由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入进行一些业务操作,只能对 Controller请求进行拦截。
应用场景:登录检查,请求执行时间等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//step1 创建多个interceptor
public class Interceptor1 implements HandlerInterceptor, Ordered {
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) {
System.out.println("CustomInterceptor....preHandle LOWEST 1" + httpServletRequest.getRequestURI());
//对浏览器的请求进行放行处理
return true;
}
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
ModelAndView modelAndView) {
System.out.println("CustomInterceptor....postHandle LOWEST 1" + httpServletRequest.getRequestURI());
}
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) {
System.out.println("CustomInterceptor....afterCompletion LOWEST 1" + httpServletRequest.getRequestURI());
}
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
public class Interceptor2 implements HandlerInterceptor, Ordered {
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) {
System.out.println("CustomInterceptor....preHandle 2" + httpServletRequest.getRequestURI());
//对浏览器的请求进行放行处理
return true;
}
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
ModelAndView modelAndView) {
System.out.println("CustomInterceptor....postHandle 2" + httpServletRequest.getRequestURI());
}
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) {
System.out.println("CustomInterceptor....afterCompletion 2" + httpServletRequest.getRequestURI());
}
public int getOrder() {
return 0;
}
}
public class Interceptor3 implements HandlerInterceptor, Ordered {
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) {
System.out.println("CustomInterceptor....preHandle HIGHEST 3" + httpServletRequest.getRequestURI());
//对浏览器的请求进行放行处理
return true;
}
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
ModelAndView modelAndView) {
System.out.println("CustomInterceptor....postHandle HIGHEST 3" + httpServletRequest.getRequestURI());
}
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) {
System.out.println("CustomInterceptor....afterCompletion HIGHEST 3" + httpServletRequest.getRequestURI());
}
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
//step2 添加配置
@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new Interceptor1())
.addPathPatterns("/**");
registry.addInterceptor(new Interceptor2())
.addPathPatterns("/**");
registry.addInterceptor(new Interceptor3())
.addPathPatterns("/**");
}
}

多个 Interceptor 执行顺序为:
preHandle :低优先级 -> 高优先级
postHandle:高优先级 -> 低优先级
afterCompletion:高优先级 -> 低优先级

【文献】
https://blog.csdn.net/csdn13257081409/article/details/105652032
https://www.lnrcoder.cn/java/filter-interceptor.html