有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java spring启动entityManagerFactory登录后初始化

我用spring boot开发了一个JavaFX应用程序。此应用程序使用本地数据库(H2),但数据库连接属性(如数据库名称、用户名和密码)由用户在登录屏幕上输入

但是SpringBoot初始化AppConfig中定义的所有bean。java,我无法初始化javafx场景以显示UI

将排除放在@EnableAutoConfiguration注释中没有帮助

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

SpringBoot仍然尝试连接到数据库

当然,一旦用户输入db name、username/password,springboot应该初始化与数据库相关的bean,或者以某种方式强制springboot进行初始化,因为稍后应用程序功能需要它们

谢谢你的提示


共 (4) 个答案

  1. # 1 楼答案

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

    我建议避免使用spring boot starter JPA和datasource属性进行初始化

    保留datasource的属性,但将其命名为spring boot不需要的名称。然后,我将通过创建datasource对象在登录时初始化datasource

    另一个选项是定义一个数据源bean并将其标记为懒惰

  3. # 3 楼答案

    您可以使用包装器提供自己的数据源bean,该包装器仅在需要连接时初始化数据源

    您的数据源包装器可以提供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 autoconfiguration尝试在bean初始化期间连接到数据库(即JpaBaseConfiguration中的JpaVendorAdapterbean),因此提供数据源包装器无法完成这项工作

    可以在here中找到可能的解决方案

  4. # 4 楼答案

    听起来你想要一种动态/懒惰的数据源bean。 您可以尝试通过创建扩展org的自定义RoutingDatasource实现来实现这一点。springframework。jdbc。数据源。查找。AbstractRoutingDataSource

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

    您可以尝试在RoutingDatasource中使用某种类型的NoopDatasource,以便在需要数据源但用户尚未提供凭据的情况下使用