IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> druid源码解读--filter-chain设计模式 -> 正文阅读

[Java知识库]druid源码解读--filter-chain设计模式

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<>();

    /**
     * 向校验链中添加校验项目
     *
     * @param checker 校验项目
     * @return 校验链本身
     */
    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);
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-15 15:42:36  更:2021-11-15 15:43:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:54:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码