链式开发,增加代码可读性,切面思想较少代码冗余,仅供参考学习。
一、实用类
链式主流程1:
import com.HandlerChain;
import com.RequestData;
import com.ResponData;
import com.Filter1ControlHandler;
import com.Filter2ControlHandler;
import com.result.Result;
public class MenthHandlerChain extends HandlerChain<Result<ResponData>, RequestData> {
@Override
protected void initHandlers() {
//过滤实现1
addHandler(new Filter1ControlHandler<>());
//过滤实现2
addHandler(new Filter2ControlHandler<>());
}
}
过滤实现2:
import com.Handler;
import com.ResponData;
import com.RequestData;
import com.ApplicationContextHolder;
import javax.annotation.Resource;
public class Filter1ControlHandler<T> extends Handler<Result<ResponData>, RequestData> {
private static final Logger logger = LoggerFactory.getLogger(Filter1ControlHandler.class);
@Resource
private RiskService riskService;//外部依赖接口
public Filter1ControlHandler() {
ApplicationContextHolder.autowire(this);
}
@Override
public Result<ResponData> invoke(RequestData context) {
try {
//利用入参context中的参数进行业务过滤
String param = context.getParam();
boolean riskStatus = riskService.risk(param);
if(!riskStatus){
return this.getNext().invoke(context);//继续透传入参到下一个过滤
}
return Result.failResult(3001, "被风控了,结束链式");
} catch (Exception e) {
logger.error("Filter1ControlHandler exception", e);
return Result.failResult(3001, "被风控了,结束链式");
}
}
}
过滤实现3:
import com.Handler;
import com.ResponData;
import com.RequestData;
import com.ApplicationContextHolder;
import javax.annotation.Resource;
public class Filter2ControlHandler<T> extends Handler<Result<ResponData>, RequestData> {
private static final Logger logger = LoggerFactory.getLogger(Filter2ControlHandler.class);
@Resource
private ActService actService ;//外部依赖接口
public Filter2ControlHandler() {
ApplicationContextHolder.autowire(this);
}
@Override
public Result<ResponData> invoke(RequestData context) {
try {
//利用入参context中的参数进行业务过滤
String param = context.getParam();
ResponData responData= actService .get(param);
if(null!=responData){
return Result.of(responData);//返回数据,结束链式
}
return Result.failResult(3002, "无数据,结束链式");
} catch (Exception e) {
logger.error("Filter1ControlHandler exception", e);
return Result.failResult(3002, "无数据,结束链式");
}
}
}
实例化类:
@Configuration
public class Config {
@Bean
public ApplicationContextHolder applicationContextHolder() {
return new ApplicationContextHolder();
}
}
二、工具类
链式类1:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class HandlerChain<T, S extends HandlerContext> {
private static final Logger LOGGER = LoggerFactory.getLogger(HandlerChain.class);
private Handler<T, S> chain;
private List<Handler<T, S>> handlers;
private Handler<T, S> lastHandler;
private ConfigContext configContext;
public static <T, S extends HandlerContext> HandlerChain build(List<Handler<T, S>> handlers,
Handler<T, S> lastHandler,
ConfigContext configContext) {
return new HandlerChain<>(handlers, lastHandler, configContext);
}
public static <T, S extends HandlerContext> HandlerChain build(List<Handler<T, S>> handlers,
Handler<T, S> lastHandler) {
return new HandlerChain<>(handlers, lastHandler, null);
}
public static <T, S extends HandlerContext> HandlerChain build(List<Handler<T, S>> handlers,
ConfigContext configContext) {
return new HandlerChain<>(handlers, null, configContext);
}
public static <T, S extends HandlerContext> HandlerChain build(List<Handler<T, S>> handlers) {
return new HandlerChain<>(handlers, null, null);
}
private HandlerChain(List<Handler<T, S>> handlers, Handler<T, S> lastHandler,
ConfigContext configContext) {
this.handlers = handlers;
this.lastHandler = lastHandler;
this.configContext = configContext;
this.build();
}
public HandlerChain(ConfigContext configContext) {
this.configContext = configContext;
this.handlers = new ArrayList<>();
initHandlers();
this.build();
}
public HandlerChain() {
this.handlers = new ArrayList<>();
initHandlers();
this.build();
}
protected void initHandlers() {
}
protected void addHandler(Handler<T, S> handler) {
this.handlers.add(handler);
}
public List<Handler<T, S>> getHandlers() {
return handlers;
}
public void setHandlers(List<Handler<T, S>> handlers) {
this.handlers = handlers;
}
public T invoke(S context) {
return this.getChain().invoke(context);
}
protected Handler<T, S> getChain() {
return this.chain;
}
private void build() {
try {
this.chain = lastHandler;
if (configContext == null) {
configContext = new ConfigContext();
}
for (int i = handlers.size() - 1; i >= 0; i--) {
Handler<T, S> handler = handlers.get(i);
if (handler != null) {
if (handler.getNext() != null) {
LOGGER.warn("Handler {} has been already used, maybe it's singleton, will try to clone new " +
"instance instead of it", handler);
handler = handler.clone();
}
handler.setConfigContext(configContext);
handler.setNext(chain);
this.chain = handler;
}
}
} catch (Exception e) {
LOGGER.error("Init handler chain error", e);
throw new IllegalArgumentException("Init handler chain error", e);
}
}
}
链式类2:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class HandlerContext {
private Map<String, Object> variableMap = new ConcurrentHashMap<>();
public void setVariable(String key, Object value) {
variableMap.put(key, value);
}
public <T> T getVariable(String key) {
return (T) variableMap.get(key);
}
}
链式类3:
import java.io.Serializable;
public abstract class Handler<T, S extends HandlerContext> implements Serializable, Cloneable {
private ConfigContext configContext;
private Handler<T, S> next;
/**
* 执行处理器
* @param context 执行上下文
* @return
*/
public abstract T invoke(S context);
public Handler<T, S> getNext() {
return next;
}
public void setNext(Handler<T, S> next) {
this.next = next;
}
public ConfigContext getConfigContext() {
return configContext;
}
public void setConfigContext(ConfigContext configContext) {
this.configContext = configContext;
}
@Override
public Handler<T, S> clone() {
try {
return (Handler<T, S>) super.clone();
} catch (CloneNotSupportedException e) {
throw new IllegalArgumentException("Filter clone not supported", e);
}
}
}
链式类4:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ConfigContext {
private Map<String, Object> variableMap = new ConcurrentHashMap<>();
public void setVariable(String key, Object value) {
variableMap.put(key, value);
}
public <T> T getVariable(String key) {
return (T) variableMap.get(key);
}
}