数据源组件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);
以上介绍的三种配置方式,各有优劣。
以上是关于数据源组件druid filter的扩展机制及spring boot 环境下的几种配置方式的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot随笔-SpringBoot集成Druid