79.1 配置自定义的数据源

在你的配置中自定义那种类型的@Bean来配置你自己的数据源。需要的时候,Spring Boot将会重复使用你的数据源,包括数据库的初始化。如果你需要具体化一些配置,你可以轻松的将你的数据源跟环境绑定(24.7.1. 第三方配置)。

下面的例子演示了如何在bean中定义数据源:

@Bean
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() {
    return new FancyDataSource();
}

下面的例子展示了如何通过设置属性来定义一个数据源:

app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30

假设对于这个URL,你的FancyDataSource有一个常规的JavaBean属性。用户名和池的大小,这些设置将会在数据源对其它组件可用之前,被自动绑定。常规的数据库初始化也将会发生(这样,相关的spring.datasource.*的子集仍旧可以在你的自定义配置中使用)。

如果你正在配置一个自定义的JNDI数据源,你可以应用相同的原则:

@Bean(destroyMethod="")
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() throws Exception {
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS");
}

Spring Boot也提供了一个工具生成器类DataSourceBuilder,可以被用于生成标准的数据源(如果它在类路径上)。在类路径上哪个可用,生成器就会用哪个。它也会基于JDBC URL自动探测驱动。

下面的示例演示如何使用DataSourceBuilder创建数据源:

@Bean
@ConfigurationProperties("app.datasource")
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

运行一个带有那个数据源的应用,只需要连接信息。也可以提供指定池的设置。检查将要在运行时使用的实现,来获取更多细节。

下面的例子展示了如何通过设置属性来定义JDBC数据源:

app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30

然而,这里有一个陷阱。因为连接池的实际类型没有被暴露,对于你自定义的数据源,在元数据中没有键值生成。同时,在你的IDE中也没有补全的方法(数据源接口没有暴露任何属性)。如果你的类路径里存在Hikari,基本的设置将不会生效,因为Hikari没有url参数(但有一个jdbcUrl参数)。你将不得不如下重写你的配置:

app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.maximum-pool-size=30

你可以通过强制连接池使用和返回一个专用的实现而不是数据源来处理。你将无法在运行时改变实现,但是选项的列表将会明确。

下面的示例演示如何使用DataSourceBuilder创建HikariDataSource

@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource() {
    return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

通过利用DataSourceProperties,你可以走得更远。如果没有URL(带有可感测的用户名和密码)被提供,它提供一个默认的内嵌的数据库。你可以从任何DataSourceProperties的状态,轻松地初始化一个DataSourceBuilder。这样,你幸好可以注入Spring Boot自动创建的数据源。可是,那将会把你的配置分离为两个命名空间:spring.datasource上的url,用户名,密码,类型和驱动,以及在你自定义的命名空间(app.datasource)上的剩余部分。为了避免这种情况,你可以在你自定义的命名空间,重新定义一个自定义的DataSourceProperties

@Bean
@Primary
@ConfigurationProperties("app.datasource")
public DataSourceProperties dataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource(DataSourceProperties properties) {
    return properties.initializeDataSourceBuilder().type(HikariDataSource.class)
            .build();
}

这项设置与Spring Boot默认为你做的刚好是一对,除了一个专用的连接池被选择(在代码里),同时它的设置被暴露在相同的命名空间。因为DataSourceProperties会为你处理url或者jdbcUrl的翻译,你可以像这样配置它:

app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.maximum-pool-size=30

因为你自定义的配置选择使用Hikari,app.datasource.type将会失效。实际上,生成器将会被任何你设置在那儿的值初始化,然后被.type()的调用重写。

具体详情可参考“Spring Boot特性”章节中的29.1. 配置数据源DataSourceAutoConfiguration类源码。

最后更新于