filter-chain设计模式
if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(this);
return filterChain.dataSource_connect(this, maxWaitMillis);
}
if (this.pos < filterSize) {
return nextFilter()
.connection_connect(this, info);
}
filter-chain设计模式的类或接口主要有一下几个Filter、FilterAdapter、FilterChain、FilterChainImpl、FilterEventAdapter、FilterManager 以及两个具体的filter:StatFilter、LogFilter
Filter接口
定义了过滤器的功能,入参是FilterChain
ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException;
FilterChain接口
定义了这个过滤器链的事件方法。
ConnectionProxy connection_connect(Properties info) throws SQLException;
FilterChainImpl实现类
1、具体处理chain中事件的具体事件;
2、将请求分发给下一个filter‘“处理” (pos位置)
public ConnectionProxy connection_connect(Properties info) throws SQLException {
if (this.pos < filterSize) {
return nextFilter()
.connection_connect(this, info);
}
Driver driver = dataSource.getRawDriver();
String url = dataSource.getRawJdbcUrl();
Connection nativeConnection = driver.connect(url, info);
if (nativeConnection == null) {
return null;
}
return new ConnectionProxyImpl(dataSource, nativeConnection, info, dataSource.createConnectionId());
}
FilterEventAdapter类
将我们关注的具体事件,通过适配器的设计模式,分为doBefore,do,doAfter三种事件
public ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException {
connection_connectBefore(chain, info);
ConnectionProxy connection = super.connection_connect(chain, info);
connection_connectAfter(connection);
return connection;
}
StatFilter、LogFilter类
实现了doBefore,doAfter,这样的话,配置了这两个filter的类就可以做一些切面的事情了
public ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException {
ConnectionProxy connection = null;
long startNano = System.nanoTime();
long startTime = System.currentTimeMillis();
long nanoSpan;
long nowTime = System.currentTimeMillis();
JdbcDataSourceStat dataSourceStat = chain.getDataSource().getDataSourceStat();
dataSourceStat.getConnectionStat().beforeConnect();
try {
connection = chain.connection_connect(info);
nanoSpan = System.nanoTime() - startNano;
} catch (SQLException ex) {
dataSourceStat.getConnectionStat().connectError(ex);
throw ex;
}
dataSourceStat.getConnectionStat().afterConnected(nanoSpan);
if (connection != null) {
JdbcConnectionStat.Entry statEntry = getConnectionInfo(connection);
dataSourceStat.getConnections().put(connection.getId(), statEntry);
statEntry.setConnectTime(new Date(startTime));
statEntry.setConnectTimespanNano(nanoSpan);
statEntry.setEstablishNano(System.nanoTime());
statEntry.setEstablishTime(nowTime);
statEntry.setConnectStackTrace(new Exception());
dataSourceStat.getConnectionStat().setActiveCount(dataSourceStat.getConnections().size());
}
return connection;
}
FilterManager类
工具类,提供了filter的spi方式加载方式,也在于一种解耦,将filter和chain解耦,方便日后扩展。
Java的SPI机制:(service provider interface ) 对于该机制的详情概述请自行百度。其实Spi简单的是提供给服务提供商的开发者使用和扩展的(其实是接口编程+策略模式+配置文件的一种方式)
public static void loadFilter(List<Filter> filters, String filterName) throws SQLException {
if (filterName.length() == 0) {
return;
}
String filterClassNames = getFilter(filterName);
if (filterClassNames != null) {
for (String filterClassName : filterClassNames.split(",")) {
if (existsFilter(filters, filterClassName)) {
continue;
}
Class<?> filterClass = Utils.loadClass(filterClassName);
if (filterClass == null) {
LOG.error("load filter error, filter not found : " + filterClassName);
continue;
}
Filter filter;
try {
filter = (Filter) filterClass.newInstance();
} catch (ClassCastException e) {
LOG.error("load filter error.", e);
continue;
} catch (InstantiationException e) {
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
} catch (IllegalAccessException e) {
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
} catch (RuntimeException e) {
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
}
filters.add(filter);
}
return;
}
if (existsFilter(filters, filterName)) {
return;
}
Class<?> filterClass = Utils.loadClass(filterName);
if (filterClass == null) {
LOG.error("load filter error, filter not found : " + filterName);
return;
}
try {
Filter filter = (Filter) filterClass.newInstance();
filters.add(filter);
} catch (Exception e) {
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
}
}
业务开发系统中如何使用责任链?
1、多层校验
public class CheckChain<P> implements CheckOperation<P> {
private final List<CheckOperation<P>> checkChain = new ArrayList<>();
public CheckChain<P> addChecker(CheckOperation<P> checker) {
this.checkChain.add(checker);
return this;
}
@Override
public void doCheck(P p) {
checkChain.forEach(checker -> checker.doCheck(p));
}
}
@Component
public class GenerateChecker implements CheckOperation<Request> {
@Override
public void doCheck(Request request) {
......
}
}
@Override
public Result<String> generateSporadicOrderForEtc(Request request) {
CheckOperation checkChain = new CheckChain()
.addChecker(GenerateChecker);
checkChain.doCheck(request);
......
}
2、任务编排
编排多个原子能力 CheckChain,每个原子能力实现具体业务操作,具体的业务功能接口中编排各个chain功能。
ProcessOperation checkChain = new ProcessChain()
.addChecker(publishOffer);
.addChecker(bindBackOfferStock);
.addChecker(syncStockRoute);
.addChecker(setVirtualProductExtension);
checkChain.doProcess(sporadicHeaderRequest);
|