责任链模式-在工作中的应用

需求是对于@JmsListener的消息的处理,监听到的记录处理如下

1.更新记录状态

2.发送通知给客户

3.其他处理

刚好可以使用链式的处理

首先定义一个Response处理的接口

public interface ResponseHandler {
	void process(JSONObject jsonObj) throws Exception;
	
	//使用java8的default默认实现
	default void process(JSONObject jsonObj,
	         ListenerHandlerChainExecutor chain) throws Exception{
		this.process(jsonObj);
		if(chain!=null)
			chain.process(jsonObj);//链式调用
	}
}

定义chain来一个个的处理ResponseHandler的实例,这里借鉴了RestTemplate的interceptor的处理,
用了Iterator来处理

public class ListenerHandlerChainExecutor implements  ResponseHandler{
	private Iterator<ResponseHandler> it= null ;
	private List<ResponseHandler> handlers = null;
	public ListenerHandlerChainExecutor(List<ResponseHandler> handlers){
		this.handlers = handlers;
		it = this.handlers.iterator();
	}
	@Override
	public void process(JSONObject jsonObj) throws Exception {
	
		if(it.hasNext()){
			ResponseHandler nextHandler = it.next();
			//ResponseHandler 接口里的默认实现,java8的default
			//!!!!关键的调用,实现了链式处理
			nextHandler.process(jsonObj,this);
		}
	}
	
}

更新记录的handler

@Component
@Order(1) //定义顺序
public class UpdateStatusHandler implements ResponseHandler {

	@Autowired
	RequestMapper mapper;
	
	@Override
	public void process(JSONObject jsonObj) throws Exception {
		RequestValue request = new RequestValue();
		int requestky =jsonObj.getInt("requestKy");
		request.setRequestKy(requestky);
		request.setRqstStatus(jsonObj.getInt("code"));
		mapper.processRequest(request);
	}   

}

发送通知给客户

@Component
@Order(2)//定义顺序
public class NotifyCustomerHandler implements ResponseHandler {

    public void process(JSONObject jsonObj) throws Exception {
        
        ....
    }
}
@Component
public class xxxMQListener {
   //顺序的维护使用@Order接口
   //Autowired也可以注入一种类型的集合
   //也可以使用@Qualify自定义一个annotation,
   //类似springcloud 里的 @loadbalance
	@Autowired(required=false)
	List<ResponseHandler> list = Collections.emptyList();
	
	@JmsListener(destination="a.b.c.QUEUE")
	public void onMessage(Message message) {
		if(message instanceof JMSTextMessage){
			JMSTextMessage objMsg  = (JMSTextMessage)message;
			try {
				String json = objMsg.getText();
				JSONObject jsonObj = new JSONObject(json);
				//构造出一个chain
			    new ListenerHandlerChainExecutor(list).process(jsonObj);
			} catch (Exception e) {
				logger.error(....);
			}
		}
	

对比servlet filter模式

servlet filter 下面主要是几个主要的类

  • Filter
  • HttpFilter
  • FilterChain
  • ApplicationFilterChain
public interface Filter {
  public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;
 }

HttpFilter extends GenericFilter ,GenericFilter implements Filter.如下

public abstract class HttpFilter extends GenericFilter {
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
             ...
            doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
    }
     protected void doFilter(HttpServletRequest request, HttpServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        chain.doFilter(request, response);
    }
}
public interface FilterChain {
  public void doFilter(ServletRequest request, ServletResponse response)
            throws IOException, ServletException;
}

ApplicationFilterChain 里

  • addFilter:把filterConfig加入到 ApplicationFilterConfig[] filters,filterConfig.getFilter()可以获取到Filter类。在加入前会判断filters数组是否已经满了,如果已经满了扩容1个。
  • doFilter: 调用internalDoFilter,其实就是一个个去调用
public final class ApplicationFilterChain implements FilterChain {
    private int pos = 0;
    private int n = 0;
    private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
     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;

    }

   public void  doFilter(ServletRequest request, ServletResponse response)
        throws IOException, ServletException {
			...
			internalDoFilter(req,res);
			...	
     }
      private void internalDoFilter(ServletRequest request,
                                  ServletResponse response)
        throws IOException, ServletException {

        if (pos < n) {
            ApplicationFilterConfig filterConfig = filters[pos++];
  
              Filter filter = filterConfig.getFilter();
              ...
             filter.doFilter(request, response, this); //注意这个
              ...
            return;
        } 
        
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值