数据源组件druid filter的扩展机制及spring boot 环境下的几种配置方式

Posted Dreamer who

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据源组件druid filter的扩展机制及spring boot 环境下的几种配置方式相关的知识,希望对你有一定的参考价值。

        Druid的监控统计功能是通过filter-chain扩展实现,filter给开发者带来了很好的扩展性,使得我们可以自定义实现一些功能。

在spring boot环境下,除了系统环境变量及jdbc url方式配置filter,大多常用的有以下几种:

(1)在项目中像平时写类加注解的方式

例如:

@Component
public class DemoFilter extends FilterEventAdapter 
    @Override
    public void init(DataSourceProxy dataSource) 
        super.init(dataSource);
    

那这个自定义的filter就自动被注入到DruidDataSource 的filter集合中,要使用这种,实例化DruidDataSource的方式还得借助druid-spring-boot-starter,

@Configuration
public class DataSourceConfig 
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Bean(name = "dataSource")
    @ConfigurationProperties("spring.datasource.sdcuike")
    public DataSource dataSource() 
        logger.info("Init DruidDataSource");
        return DruidDataSourceBuilder.create().build();
    

为了和spring boot 融合,用了装饰者模式com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper。使得项目中的所有filter实例自动注入:

 @Autowired(required = false)
    public void autoAddFilters(List<Filter> filters)
        super.filters.addAll(filters);
    

上述代码使用了spring 的setter注入方式。

 

(2)实现filter自定义扩展类,并在文件META-INF/druid-filter.properties配置:别名=实现类,并且在数据源属性中配置

 

spring:
  datasource:
    sdcuike:
      filters: stat,demo3Filter

其扩展思想来源于SPI,其实dubbo的扩展机制也是起源于SPI,在META-INF/druid-filter.properties配置的类会在合适的条件加载类型,并根据配置的别名来决定是不是实例化。

其加载的详细部分代码在com.alibaba.druid.filter.FilterManager#loadFilterConfig(java.util.Properties, java.lang.ClassLoader)

 private static void loadFilterConfig(Properties filterProperties, ClassLoader classLoader) throws IOException 
        if (classLoader == null) 
            return;
        
        
        for (Enumeration<URL> e = classLoader.getResources("META-INF/druid-filter.properties"); e.hasMoreElements();) 
            URL url = e.nextElement();

            Properties property = new Properties();

            InputStream is = null;
            try 
                is = url.openStream();
                property.load(is);
             finally 
                JdbcUtils.close(is);
            

            filterProperties.putAll(property);
        
    

 

  别名注入的方式也是通过spring 的setter方式注入的:

com.alibaba.druid.pool.DruidAbstractDataSource#setFilters

    public void setFilters(String filters) throws SQLException 

 

(3)基于java标准的SPI加载机制+注解@AutoLoad 实现

我们需要在文件/src/main/resources/META-INF/services/com.alibaba.druid.filter.Filter,按照java标准的SPI规范配置扩展的filter类型,如com.sdcuike.springboot.druid.filter.Demo2Filter,并且在类上加上注解@AutoLoad即可。

@AutoLoad
public class Demo2Filter extends FilterEventAdapter 
    @Override
    public void init(DataSourceProxy dataSource) 
        super.init(dataSource);
    

其实现代码在com.alibaba.druid.pool.DruidDataSource#initFromSPIServiceLoader

  /**
     * load filters from SPI ServiceLoader
     * 
     * @see ServiceLoader
     */
    private void initFromSPIServiceLoader() 
        if (loadSpifilterSkip) 
            return;
        

        if (autoFilters == null) 
            List<Filter> filters = new ArrayList<Filter>();
            ServiceLoader<Filter> autoFilterLoader = ServiceLoader.load(Filter.class);

            for (Filter filter : autoFilterLoader) 
                AutoLoad autoLoad = filter.getClass().getAnnotation(AutoLoad.class);
                if (autoLoad != null && autoLoad.value()) 
                    filters.add(filter);
                
            
            autoFilters = filters;
        

        for (Filter filter : autoFilters) 
            if (LOG.isInfoEnabled()) 
                LOG.info("load filter from spi :" + filter.getClass().getName());
            
            addFilter(filter);
        
    

 

以上介绍的三种配置方式,各有优劣。

https://github.com/sdcuike/spring-boot2-practice/tree/druid_filter/src/main/java/com/sdcuike/springboot/druid/filter

以上是关于数据源组件druid filter的扩展机制及spring boot 环境下的几种配置方式的主要内容,如果未能解决你的问题,请参考以下文章

Druid.jar包

Druid.jar包

SpringBoot随笔-SpringBoot集成Druid

SpringBoot随笔-SpringBoot集成Druid

JDBC连接池监控组件(Druid)

Springboot整合Druid数据源