在我的SpringBoot项目中,我在
application.yml
下有src/main/resources/
文件:
server:
port: 8080
spring:
datasource:
driver-class-name: org.sqlite.JDBC
...
我想将上面定义的属性绑定到 Java 类,因此我创建了我的 Java 类:
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DBConfig {
// I wished spring-boot could automatically bind it with 'driver-class-name' in application.yml
private String driverClassName;
...
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
...
return dataSource;
}
}
正如您在上面看到的,在我的 Java 类中,我有注释
@Configuration
和 @ConfigurationProperties(prefix = "spring.datasource")
,我还指定了正确的前缀。
但是当我开始运行我的应用程序时,我不断收到错误:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/my/webapp/config/DBConfig.class]: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception with message: Property 'driverClassName' must not be empty
该错误基本上告诉
driverClassName
是一个空字符串,因此绑定对我不起作用。我想知道我错过了什么?
我使用的是 SQLite 数据库,它在 SpringBoot 生态系统中的支持不如其他数据库(例如 MySQL、MariaDB 等)。因此,我提供了一个数据源 bean 类,将
application.yml
中的数据库配置绑定到手动创建的 bean 类。如果有人认为即使使用 SQLite 数据库也没有必要手动创建此数据源 bean,请告诉我。
配置属性的常用方法是将它们保存在单独的类中。您可以尝试以下操作:
@Configuration
@EnableConfigurationProperties(MyConfigurationProperties.class)
public class DBConfig {
@Autowired
private MyConfigurationProperties props;
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(props.getDriverClassName());
// ...
return dataSource;
}
}
你的属性类将如下所示:
@ConfigurationProperties(prefix = "spring.datasource")
public class MyConfigurationProperties {
private String driverClassName;
}
但我不确定这是否是最好的解决方案,因为 Spring 已经有自己的配置属性类绑定到前缀
spring.datasource
。
第二个选项是使用 Spring 配置属性:
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
// ...
@Configuration
@EnableCOnfigurationProperties(DataSourceProperties.class)
public class DBConfig {
@Autowired
private DataSourceProperties props;
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(props.getDriverClassName());
// ...
return dataSource;
}
}