前面我们看完了整个DruidDataSource初始化流程,但是其实Druid除了最核心的数据源之外,还有其他需要自动配置的,细心的人可能看到了,就是利用@Import注解导入的四个类。
public class DruidFilterConfiguration {
@Bean
@ConfigurationProperties(FILTER_STAT_PREFIX)
@ConditionalOnProperty(prefix = FILTER_STAT_PREFIX, name = "enabled")
@ConditionalOnMissingBean
public StatFilter statFilter() {
return new StatFilter();
}
@Bean
@ConfigurationProperties(FILTER_CONFIG_PREFIX)
@ConditionalOnProperty(prefix = FILTER_CONFIG_PREFIX, name = "enabled")
@ConditionalOnMissingBean
public ConfigFilter configFilter() {
return new ConfigFilter();
}
@Bean
@ConfigurationProperties(FILTER_ENCODING_PREFIX)
@ConditionalOnProperty(prefix = FILTER_ENCODING_PREFIX, name = "enabled")
@ConditionalOnMissingBean
public EncodingConvertFilter encodingConvertFilter() {
return new EncodingConvertFilter();
}
\\\\\\\\\\\\\\\\\\\\省略
}
可以看到在某些配置设置的enabled为true的时候会生成对应的bean放到spring容器里面,为后续执行filter做准备。这里如果你项目里面自定义了相同的bean,那么就不会重复创建。
@ConditionalOnProperty("spring.datasource.druid.aop-patterns")
public class DruidSpringAopConfiguration {
@Bean
public Advice advice() {
return new DruidStatInterceptor();
}
@Bean
public Advisor advisor(DruidStatProperties properties) {
return new RegexpMethodPointcutAdvisor(properties.getAopPatterns(), advice());
}
@Bean
@ConditionalOnProperty(name = "spring.aop.auto", havingValue = "false")
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
}
这个是一个AOP的配置,主要实现在DruidStatInterceptor类里面,就是可以监控你用spring.datasource.druid.aop-patterns代表的所有切面,它们里面的方法调用都会被记录。有兴趣的可以去看下它的具体实现。
然后因为是依赖AOP的,如果关闭了AOP会创建一个DefaultAdvisorAutoProxyCreator。
这个是一个监控Servlet的注册,然后可以在spring里面访问。将拿到配置信息,如果有就设置,部分参数会设置默认值。实现如下:
@Bean
public ServletRegistrationBean statViewServletRegistrationBean(DruidStatProperties properties) {
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean();
registrationBean.setServlet(new StatViewServlet());
registrationBean.addUrlMappings(config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*");
if (config.getAllow() != null) {
registrationBean.addInitParameter("allow", config.getAllow());
} else {
registrationBean.addInitParameter("allow", DEFAULT_ALLOW_IP);
}
if (config.getDeny() != null) {
registrationBean.addInitParameter("deny", config.getDeny());
}
if (config.getLoginUsername() != null) {
registrationBean.addInitParameter("loginUsername", config.getLoginUsername());
}
if (config.getLoginPassword() != null) {
registrationBean.addInitParameter("loginPassword", config.getLoginPassword());
}
if (config.getResetEnable() != null) {
registrationBean.addInitParameter("resetEnable", config.getResetEnable());
}
return registrationBean;
}
@Bean
public FilterRegistrationBean webStatFilterRegistrationBean(DruidStatProperties properties) {
DruidStatProperties.WebStatFilter config = properties.getWebStatFilter();
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
WebStatFilter filter = new WebStatFilter();
registrationBean.setFilter(filter);
registrationBean.addUrlPatterns(config.getUrlPattern() != null ? config.getUrlPattern() : "/*");
registrationBean.addInitParameter("exclusions", config.getExclusions() != null ? config.getExclusions() : "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
if (config.getSessionStatEnable() != null) {
registrationBean.addInitParameter("sessionStatEnable", config.getSessionStatEnable());
}
if (config.getSessionStatMaxCount() != null) {
registrationBean.addInitParameter("sessionStatMaxCount", config.getSessionStatMaxCount());
}
if (config.getPrincipalSessionName() != null) {
registrationBean.addInitParameter("principalSessionName", config.getPrincipalSessionName());
}
if (config.getPrincipalCookieName() != null) {
registrationBean.addInitParameter("principalCookieName", config.getPrincipalCookieName());
}
if (config.getProfileEnable() != null) {
registrationBean.addInitParameter("profileEnable", config.getProfileEnable());
}
return registrationBean;
}
注册Druid的WebStatFilter到spring的filter里面,然后添加一些配置的参数,部分没有设置的会给默认值。
这四个组件其实大部分都是填充值,里面需要注意的是DruidSpringAopConfiguration,这里面有个DruidStatInterceptor类的实现其实东西不少,但是它是在com.alibaba.druid.support.spring包下的,不在这次druid-spring-boot-starter范围内,后面看到会记录一下的。