繁体   English   中英

登录后的Spring BootEntityManagerFactory初始化

[英]spring boot entityManagerFactory initialization after login

我用Spring Boot开发了JavaFX应用程序。 该应用程序使用本地数据库(H2),但是数据库连接属性(如数据库名称,用户名,密码)由用户在登录屏幕上输入。

但是Spring Boot会初始化AppConfig.java中定义的所有bean,并且我无法初始化javafx场景来显示UI。

将exclude放入@EnableAutoConfiguration注释无济于事。

@SpringBootApplication
@EnableAutoConfiguration(exclude= {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})   
public class MyApplication extends Application {

spring boot仍然尝试连接到数据库。

当然,一旦用户输入了数据库名称,用户名/密码,Spring Boot应该初始化与数据库相关的Bean或以某种方式强制Spring Boot进行初始化,因为稍后它们是应用程序功能所必需的。

感谢您的提示!

您可以尝试在春季引导之前启动登录屏幕,然后将输入的值设置为系统属性。 然后启动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);
}

您可以使用包装器提供自己的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); 

然后,应在首次尝试连接时初始化DataSource。

UPDATE

春季启动JPA自动配置尝试豆初始化(即在连接到数据库JpaVendorAdapter豆在JpaBaseConfiguration ),从而提供一个数据源包装不会做的工作。

可能的解决方案可以在这里找到。

在我看来,您需要一种动态/惰性数据源bean。 您可以尝试通过创建自定义的RoutingDatasource实现来实现此目的,该实现扩展了org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource

如果需要一些示例,可以搜索SessionRoutingDataSource,DynamicRoutingDatasource或MultitenantDatasource。

您可以在RoutingDatasource中尝试使用某种NoopDatasource,以解决需要将数据源放在其中但用户尚未提供凭据的情况。

我建议避免使用Spring Boot Starter JPA和数据源属性进行初始化。

保留数据源的属性,但将其命名为Spring Boot不需要的名称。然后,我将在登录时通过创建DataSource对象来初始化数据源。

另一个选择是定义一个dataSource bean并将其标记为惰性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM