责任链模式
责任链类图
如图所示
责任链示例
//处理器接口
public interface Handler {
String handle(String request);
}
//处理器基类
public abstract class BaseHandler implements Handler{
private Handler next;
@Override
public String handle(String request) {
return next.handle(request);
}
public void setNext(Handler next) {
this.next = next;
}
}
//处理器逻辑
public class ConcreteHandler1 extends BaseHandler {
@Override
public String handle(String request) {
if (canHandle(request)) {
String result = handlework(request);
if (needHanlde(result)) {
return super.handle(request);
} else {
return result;
}
} else {
return super.handle(request);
}
}
private String handlework(String request) {
return null;
}
private boolean needHanlde(String result) {
return false;
}
private boolean canHandle(String request) {
return false;
}
}
public class ConcreteHandler2 extends BaseHandler {
@Override
public String handle(String request) {
if (canHandle(request)) {
String result = handlework(request);
if (needHanlde(result)) {
return super.handle(request);
} else {
return result;
}
} else {
return super.handle(request);
}
}
private String handlework(String request) {
return null;
}
private boolean needHanlde(String result) {
return false;
}
private boolean canHandle(String request) {
return false;
}
}
Tomcat中的责任链源码
TomcatFilterChain源码
//管理FIlter的列表
public interface FilterChain {
void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}
public final class ApplicationFilterChain implements FilterChain {
private int pos = 0;
private int n = 0;
@Override
public void doFilter(ServletRequest request, ServletResponse response){
// Call the next filter if there is one
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = filterConfig.getFilter();
filter.doFilter(request, response, this);
}else{
servlet.service(request, response);
}
}
void addFilter(ApplicationFilterConfig filterConfig) {
// Prevent the same filter being added multiple times
for(ApplicationFilterConfig filter:filters)
if(filter==filterConfig)
return;
// filters长度
if (n == filters.length) {
ApplicationFilterConfig[] newFilters =
new ApplicationFilterConfig[n + INCREMENT];
System.arraycopy(filters, 0, newFilters, 0, n);
filters = newFilters;
}
//增加filter
filters[n++] = filterConfig;
}
}
static class MyFilter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String name = servletRequest.getParameter("reqno");
//1 直接放行
if (name.equals("1")) {
System.out.println("reqno为1直接放行");
filterChain.doFilter(servletRequest, servletResponse);
}
//2 修改为1 继续过滤
else if (name.equals("2")) {
System.out.println("reqno从2修改为1");
filterChain.doFilter(servletRequest, servletResponse);
} else {
//直接不在执行下一跳
System.out.println("reqno不为目标值无法通过");
}
}
@Override
public void destroy() {
}
}
Tomcat中源码的责任链模式讲解
- AbstractFilterChain将所有Filter组合
- chain.doFilter();根据属性变量 pos游标获取当前filter的变量。调用filter的doFilter()
- filter.doFilter()中自行决定是否继续向下调用chain.doFilter()
- 因此责任链中的filter可以自行决定是否继续往下传递
Tomcat中调用时序图如下,本质上是chain->filter->chain->filter