设计模式 - 责任链模式
概念
将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
常见例子
Servlet Filter、Spring Interceptor均使用此设计模式,
最常见的是javax.servlet.Filter,Servlet Filter 是 Java Servlet 规范中定义的组件,翻译成中文就是过滤器,它可以实现对 HTTP 请求的过滤功能,比如鉴权、限流、记录日志、验证参数等。
假如要实现一个Filter,功能是针对所有的rest接口进行签名验证,签名正确的执行接口逻辑,错误的返回错误信息。我们只需要实现Filter接口即可。
@Component
public class RestSecurityFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(RestSecurityFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
// 校验安全性
HttpServletRequest httpReq = (HttpServletRequest) request;
RequestMatcher matcher = new AntPathRequestMatcher("/rest/**");
if(matcher.matches(httpReq)) {
String sign = httpReq.getHeader("sign");
// 具体签名算法略...
boolean passed = validate(httpReq);
// 校验不通过,返回错误信息,不再执行下一职责
if (!passed) {
HttpServletResponse rp = (HttpServletResponse) response;
rp.setStatus(HttpStatus.SC_BAD_REQUEST);
rp.addHeader("restful validate error",
" 400 , Method Not Allowed,please check restful called paramters ! ");
rp.getWriter()
.write("Method Not Allowed,please check restful called paramters !");
return;
}
}
}
// 放行,执行下一Filter
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
web.xml中配置
<filter>
<filter-name>restSecurityFilter</filter-name>
<filter-class>com.xxx.filter.restSecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>restSecurityFilter</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>
需求场景
业务上需要校验企业信息,依次按照企业名称、社会统一信用代码、注册号等信息进行匹配,其中每种匹配规则有自己的业务逻辑,匹配成功的,不进行下一规则匹配。全部匹配完成之后,如未匹配成功则记为匹配失败。
使用责任链的好处是各业务处理指责单一,易扩展。如后期要加入新的匹配规则,则只需要新增一个handler业务处理类即可,其它均不需要修改。
代码示例
public class CalibrateHandlerChain {
private CalibrateHandler head = null;
private CalibrateHandler tail = null;
public void addHandler(CalibrateHandler handler) {
handler.setNextHandler(null);
if (head == null) {
head = handler;
tail = handler;
return;
}
tail.setNextHandler(handler);
tail = handler;
}
public void process(List<Company> companyList) {
if (head != null) {
head.process(companyList);
}
}
}
@Component
public abstract class CalibrateHandler {
/**
* next handler,此处使用链表方式实现,也可使用数组
*/
protected CalibrateHandler nextHandler = null;
public void setNextHandler(CalibrateHandler calibrateHandler) {
this.nextHandler = calibrateHandler;
}
/**
* loop execution the method of calibrateHandlerChain
*/
public final void process(List<Company> companyList) {
// 执行当前的handle,执行完成后,进入下一handler
doHandle(companyList);
if (nextHandler != null) {
nextHandler.process(companyList);
}
}
/**
* abstract method subclass to impl
*
* @param companyList
*/
protected abstract void doHandle(List<Company> companyList);
}
@Component
@Order(1)
public class XXXHandler extends CalibrateHandler {
@Override
protected void doHandle(List<Company> companyList) {
// 企业名称匹配
}
}
@Component
@Order(2)
public class YYYHandler extends CalibrateHandler {
@Override
protected void doHandle(List<Company> companyList) {
// 社会统一信用代码匹配
}
}
...
调用方
@Service
public class xxxService {
@Autowired
private List<CalibrateHandler> calibrateHandlerList;
public void calibrateCompany(List<Company> companyList) {
CalibrateHandlerChain chain = new CalibrateHandlerChain();
// calibrateHandlerList中元素按照@Order排序,依次加入责任链
calibrateHandlerList.forEach(handler -> chain.addHandler(handler));
chain.process(companyList);
}
}