Java 为什么我的自定义数据源getConnection()抛出;SQLException:url不能为空";?

Java 为什么我的自定义数据源getConnection()抛出;SQLException:url不能为空";?,java,spring,spring-boot,Java,Spring,Spring Boot,我正在编写一个springboot(批处理)应用程序,它应该使用特定的退出代码退出。当数据库无法连接时,需要返回退出代码 我的方法是通过显式创建一个DataSourcebean,调用getConnection(),捕获并抛出一个实现ExitCodeGenerator的自定义异常,尽早处理此异常。配置如下: @Configuration @EnableBatchProcessing public class BatchConfiguration { ... @Bean @Primary @Conf

我正在编写一个springboot(批处理)应用程序,它应该使用特定的退出代码退出。当数据库无法连接时,需要返回退出代码

我的方法是通过显式创建一个
DataSource
bean,调用
getConnection()
,捕获并抛出一个实现
ExitCodeGenerator
的自定义异常,尽早处理此异常。配置如下:

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
...
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties dataSourceProps() {
    return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("spring.datasource")
public DataSource customDataSource(DataSourceProperties props) {

    DataSource ds = props.initializeDataSourceBuilder().create().build();

    try {
        ds.getConnection();

    } catch (SQLException e) {
        throw new DBConnectionException(e); // implements ExitCodeGenerator interface
    }

    return ds;
}
...
}
我希望尽可能多地重用Spring Boot自动配置,这就是我使用
@ConfigurationProperties
的原因。我不知道这是不是该走的路

调用
DataSourceProperties.getUrl()
返回配置的url(从我的属性文件):

但是为什么我调用
DataSource.getConnection()
,Spring Boot会抛出这个异常呢

java.sql.SQLException:url不能为空
在java.sql.DriverManager.getConnection(DriverManager.java:649)~[?:1.8.0141]
在java.sql.DriverManager.getConnection(DriverManager.java:208)~[?:1.8.0141]
在org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:308)~[tomcat-jdbc-8.5.15.jar:?]
在org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203)~[tomcat-jdbc-8.5.15.jar:?]
在org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735)~[tomcat-jdbc-8.5.15.jar:?]
在org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667)~[tomcat-jdbc-8.5.15.jar:?]
在org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482)[tomcat-jdbc-8.5.15.jar:?]
位于org.apache.tomcat.jdbc.pool.ConnectionPool.(ConnectionPool.java:154)[tomcat-jdbc-8.5.15.jar:?]
在org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118)[tomcat-jdbc-8.5.15.jar:?]
在org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107)[tomcat-jdbc-8.5.15.jar:?]
在org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131)[tomcat-jdbc-8.5.15.jar:?]
在com.foo.bar.BatchConfiguration.customDataSource(BatchConfiguration.java:xxx)[main/:?]
...
或者你知道一些更干净的方法来处理这种情况吗

谢谢


编辑:Spring启动版本是1.5.4

看起来您没有为数据源设置任何值

props.initializeDataSourceBuilder().create().build()不会将属性值设置为数据源。它只是创建和构建一个

尝试使用静态
DataSourceBuilder
手动设置值。您将从
dataSourceProps
bean中获得如下值:

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
...
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties dataSourceProps() {
    return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("spring.datasource")
public DataSource customDataSource(DataSourceProperties props) {

      DataSource ds = DataSourceBuilder.create()
            .driverClassName(dataSourceProps().getDriverClassName())
            .url(dataSourceProps().getUrl())
            .username(dataSourceProps().getUsername())
            .password(dataSourceProps().getPassword())
            .build();

    try {
        ds.getConnection();

    } catch (SQLException e) {
        throw new DBConnectionException(e); // implements ExitCodeGenerator interface
    }

    return ds;
}
...
}

看起来您没有为数据源设置任何值

props.initializeDataSourceBuilder().create().build()不会将属性值设置为数据源。它只是创建和构建一个

尝试使用静态
DataSourceBuilder
手动设置值。您将从
dataSourceProps
bean中获得如下值:

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
...
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties dataSourceProps() {
    return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("spring.datasource")
public DataSource customDataSource(DataSourceProperties props) {

      DataSource ds = DataSourceBuilder.create()
            .driverClassName(dataSourceProps().getDriverClassName())
            .url(dataSourceProps().getUrl())
            .username(dataSourceProps().getUsername())
            .password(dataSourceProps().getPassword())
            .build();

    try {
        ds.getConnection();

    } catch (SQLException e) {
        throw new DBConnectionException(e); // implements ExitCodeGenerator interface
    }

    return ds;
}
...
}

这个错误是微妙的,并且在这条线上

DataSource ds = props.initializeDataSourceBuilder().create().build();
create()
创建一个新的
DataSourceBuilder
,并删除预配置的属性

props.initializeDataSourceBuilder()
已返回一个设置了所有属性(url、用户名等)的
DataSourceBuilder
。因此,您只需添加新属性或直接
build()
it。因此,解决方案是删除
create()


在这个上下文中,
dataSourceProps()
方法bean也可以被删除。

错误是微妙的,并且存在于行中

DataSource ds = props.initializeDataSourceBuilder().create().build();
create()
创建一个新的
DataSourceBuilder
,并删除预配置的属性

props.initializeDataSourceBuilder()
已返回一个设置了所有属性(url、用户名等)的
DataSourceBuilder
。因此,您只需添加新属性或直接
build()
it。因此,解决方案是删除
create()


在此上下文中,
dataSourceProps()
方法bean也可以删除。

是否尝试引入致命错误以终止应用程序?我尝试尽早检测失败的数据库连接。是否尝试引入致命错误以终止应用程序?我尝试尽早检测失败的数据库连接。
DataSource ds = props.initializeDataSourceBuilder().build();