我正在编写一个 Spring Boot (Batch( 应用程序,它应该以特定的退出代码退出。要求是在无法连接数据库时返回退出代码。
我的方法是尽早处理此异常,方法是显式创建一个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 引导自动配置,这就是我使用@ConfigurationProperties
的原因。我不知道这是否是要走的路。
对DataSourceProperties.getUrl()
的调用返回配置的 url(来自我的属性文件(:
spring.datasource.url=jdbc:oracle:....
但是为什么当我调用 Spring Boot 时会抛出此异常DataSource.getConnection()
:
java.sql.SQLException: The url cannot be null
at java.sql.DriverManager.getConnection(DriverManager.java:649) ~[?:1.8.0_141]
at java.sql.DriverManager.getConnection(DriverManager.java:208) ~[?:1.8.0_141]
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:308) ~[tomcat-jdbc-8.5.15.jar:?]
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.15.jar:?]
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735) ~[tomcat-jdbc-8.5.15.jar:?]
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667) ~[tomcat-jdbc-8.5.15.jar:?]
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482) [tomcat-jdbc-8.5.15.jar:?]
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) [tomcat-jdbc-8.5.15.jar:?]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) [tomcat-jdbc-8.5.15.jar:?]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) [tomcat-jdbc-8.5.15.jar:?]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) [tomcat-jdbc-8.5.15.jar:?]
at com.foo.bar.BatchConfiguration.customDataSource(BatchConfiguration.java:xxx) [main/:?]
...
或者你知道一些更干净的方法来处理这种情况吗?
谢谢
编辑:Spring Boot 版本是 1.5.4
错误很微妙,在于行
DataSource ds = props.initializeDataSourceBuilder().create().build();
该create()
将创建一个新DataSourceBuilder
并擦除预配置的属性。
props.initializeDataSourceBuilder()
已经返回了一个设置了所有属性(url、用户名等(的DataSourceBuilder
。因此,您只需添加新属性或直接build()
它。所以解决方案是删除create()
:
DataSource ds = props.initializeDataSourceBuilder().build();
在此上下文中,也可以删除dataSourceProps()
方法bean。
您似乎没有为数据源设置任何值。
props.initializeDataSourceBuilder().create().build();
不会将属性的值设置为数据源。它只是创建并构建一个。
尝试使用静态DataSourceBuilder
手动设置值。您将从dataSourceProps
豆中获取值,如下所示:
@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;
}
...
}