一、springboot中使用数据源的依赖
(1)、JDBC启动器
(2)、数据库连接依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
二、数据源自动装配源码查看逻辑
DataSourceAutoConfiguration这个自动配置类。找到自动配置类以后,重点看两个东西:①、@EnableConfigurationProperties注解,这个注解能帮助我们了解能够在springboot配置文件中设置哪些参数。②、去找@Bean注解修饰的方法或者@Configuration修饰的内部类,这个注解能够帮助我们了解springboot托管了哪些bean。
按照上述逻辑,一个个去找,首先是自动配置类。
@Configuration(proxyBeanMethods = false)
// 需要导入DataSource类,还得确保有EmbeddedDatabaseType类
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
// 第一个重点,需要配数据源参数时候,就去找DataSourceProperties
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {}
接下来,循着之前的逻辑,点进去看看DataSourceProperties.class , 这里注意一下,最好去看set方法后面的参数名,真正注入还是看他
// 看到这里我们就知道了,配置前缀为spring.datasource
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
// 这里我只挑了最基本的、最重要的四个参数
// 也就是配置数据库连接的驱动、url、用户名以及密码
// 比如配驱动 spirng.datasource.driverClassName = com.mysql.jbdc.Driver
private String driverClassName;
private String url;
private String username;
private String password;
}
看完配置,接下来看看springboot默认是怎么去装配数据源的,这里主要是使用了@Configuration,因为有个筛选的过程
@Configuration(proxyBeanMethods = false)
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
// Import的作用就不说了,这里看到了居然要去配置这么多数据源?但其是,里面有个筛选的逻辑,springboot默认使用hikari数据源,和c3p0、druid、dbcp都是一个东西,就是管理数据库连接的池子
@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
protected static class PooledDataSourceConfiguration {
}
点Hikari.class进去看看,里面有筛选的逻辑
// 这里的configuration是对hikari的装配
@Configuration(proxyBeanMethods = false)
// 去使用hikari首先需要有hikari的依赖,starter中正好集成了hikari
@ConditionalOnClass(HikariDataSource.class)
// IOC中不能有数据源,避免产生混淆
@ConditionalOnMissingBean(DataSource.class)
// 最关键的一步,你可以引入多个数据源,但需要在配置文件中说明使用的类型,默认使用的是hikari
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
matchIfMissing = true)
static class Hikari {
// 这里的实例化还是很简单的,就是去配置properties
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
HikariDataSource dataSource(DataSourceProperties properties) {
HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
if (StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
}
三、总结
相较于其他的自动装配,数据源的自动装配逻辑就是最常规的那一套,而且整体源代码简单,可以通过这个例子对Springboot的自动装配有个更深入的逻辑理解。
总结一下,要让sb帮你完成数据源的自动装配,你需要完成这几部:导入必须的依赖以及想要使用的数据源依赖,配置选定的数据源类型,根据业务需要配置数据源参数。
四、Druid与springboot的整合
相关的starter已经有了,所以要使用可以去直接导入。这里主要是按照上面的逻辑尝试自己去注册druid数据源,并完成后台监控的设置。
大概整理一下思路:首先需要一个java configuration类去注册DruidDataSource;然后由于druid有自己的一些参数,所以需要去指定一下配置文件中的参数设置;然后再去设置后台监控,这里也有一个有意思的点,就是springboot怎么和java web中的servlet和filter进行统一。
// 放弃autoConfiguration , 自己管理druid
// 主要为了配置那些DataSourceProperties中缺失的参数
@Bean
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.alibaba.druid.pool.DruidDataSource",
matchIfMissing = true)
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DataSource dataSource(){ DruidDataSource dataSource = new DruidDataSource(); return dataSource; }
开启后台监控,druid最优先的一点就是可以进行监控、过滤以及防护(差不多那意思)。要想使用后台监控,需要做这么两点:1、允许使用后台监控(网上一大堆);2、注册servlet。
提到了servlet注册,就来说说这个知识点,其实filter也是一样的。spring使用一个DispatcherServlet帮助我们进行原来的servlet访问,sb通过controller和视图解析器简化了我们原来的工作。但我们其实还是能够注册自己的servlet。这里就用druid的监控servlet来说明。
// springboot中配置servlet的操作
// 这里是为配置druid的后台操作
// 需要一个注册bean对象
@Bean
public ServletRegistrationBean statViewServlet(){
// 实例化注册bean对象
// 这里的StatViewServlet就是alibaba提供的一个servlet
// 第二参数是配置路由
ServletRegistrationBean<StatViewServlet> registration
= new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
// 登录这个页面肯定需要密码吧
// 我们可以通过类似于web.xml中的init-param来配置参数
HashMap<String, String> initMap = new HashMap<>();
// 看源码!!
// druid后台需要登录密码
// 这些都可以去查看ali提供的源码来知道可以配哪些参数啦
initMap.put("loginUsername", "admin");
initMap.put("loginPassword", "123456");
// 还可以配置访问权限
initMap.put("allow", "");
// 设置禁止访问
// initMap.put("deny", "");
registration.setInitParameters(initMap);
return registration;
}
访问监控页面:ip:port/druid/*即可