需求是对于@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;
}
}