我用Spring Boot开发了一个JavaFX应用程序。此应用程序使用本地数据库(H2),但是数据库连接属性(如数据库名称,用户名,密码)由用户在登录屏幕上输入。
但是spring boot会初始化AppConfig.java中定义的所有bean,而我无法初始化javafx场景来显示UI。
将排除项放入@EnableAutoConfiguration注释无济于事。
@SpringBootApplication
@EnableAutoConfiguration(exclude= {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class MyApplication extends Application {
spring boot仍然尝试连接到数据库。
当然,一旦用户输入了数据库名称,用户名/密码,Spring Boot应该初始化与数据库相关的bean或以某种方式强制Spring Boot进行初始化,因为稍后它们是应用程序功能所必需的。
感谢任何提示!
答案 0 :(得分:0)
您可以尝试在春季引导之前启动登录屏幕,然后将输入的值设置为系统属性。然后启动Spring Boot:
public static void main(String[] args) {
// Start login screen
// For all properties the user entered
System.setProperty("spring.database.xy", "<value from UI>");
SpringApplication.run(Application.class, args);
}
答案 1 :(得分:0)
您可以使用包装器提供自己的DataSource bean,该包装器仅在需要连接时才初始化数据源。
您的DataSource包装器可能会提供setUsername()
和setPassword()
,供您尝试登录时使用。
我没有尝试过,但是请告诉我是否有问题。
public class AppDataSourceWrapper implements DataSource {
private final DataSourceProperties dataSourceProperties;
private String username;
private String password;
private DataSource dataSource;
public AppDataSourceWrapper(DataSourceProperties dataSourceProperties) {
this.dataSourceProperties = dataSourceProperties;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
private DataSource getDataSource() {
if (dataSource == null) {
initDataSource();
}
return dataSource;
}
private void initDataSource() {
this.dataSource = dataSourceProperties.initializeDataSourceBuilder()
.username(username)
.password(password)
.build();
}
@Override
public Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
// other override methods omitted for brevity
}
添加到您的配置中:
@Bean
public DataSource dataSource(DataSourceProperties dataSourceProperties) {
return new AppDataSourceWrapper(dataSourceProperties);
}
根据用户访问请求,您可以执行以下操作:
AppDataSourceWrapper dsWrapper = (AppDataSourceWrapper) dataSource;
dsWrapper.setUsername(username);
dsWrapper.setPassword(password);
然后应在首次尝试连接时初始化数据源。
Spring Boot JPA自动配置尝试在bean初始化期间(即JpaVendorAdapter
中的JpaBaseConfiguration
bean)连接到数据库,因此提供数据源包装器将无法完成工作。
可能的解决方案here。
答案 2 :(得分:0)
听起来像您想要一种动态/惰性数据源bean。 您可以尝试通过创建自定义的RoutingDatasource实现来实现此目的,该实现扩展了 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource 。
如果需要一些示例,可以搜索SessionRoutingDataSource,DynamicRoutingDatasource或MultitenantDatasource。
您可以尝试在RoutingDatasource中使用某种NoopDatasource,以解决需要将数据源放在其中但用户尚未提供凭据的情况。
答案 3 :(得分:0)
我建议避免使用Spring Boot Starter JPA和数据源属性进行初始化。
保留数据源的属性,但将其命名为Spring Boot不需要的名称。然后,我将在登录时通过创建DataSource对象来初始化数据源。
另一种选择是定义一个dataSource bean并将其标记为惰性。