小编典典

Spring Boot与基于会话的数据源

java

我一直在整理应该是Web应用程序的一个非常常见的用例。我有一个使用REST信息库,JPA等的Spring-Boot应用程序。问题是我有两个数据源:

  • 包含用户身份验证信息的嵌入式H2数据源
  • MySQL数据源,用于特定于已验证用户的实际数据

因为第二个数据源是特定于已验证用户的,所以我尝试使用AbstractRoutingDataSource根据验证后的主要用户路由到正确的数据源。

绝对让我抓狂的是,Spring-
Boot正在与我搏斗,以在启动时实例化此数据源。我已经尝试了所有我能想到的东西,包括Lazy和Scope批注。如果我使用Session作用域,则应用程序将引发有关启动时不存在任何会话的错误。@Lazy似乎根本没有帮助。无论我使用什么注释,该数据库都是在Spring
Boot启动时实例化的,并且找不到任何导致整个应用程序崩溃的查找键。

另一个问题是,Rest Repository API具有IMO指定指定要使用的实际数据源的可怕方法。如果使用Spring
Boot有多个数据源,则必须弄混Qualifier批注,这是运行时调试的噩梦。

任何建议将不胜感激。


阅读 231

收藏
2020-11-30

共1个答案

小编典典

您的问题与身份验证管理器配置有关。所有示例和指南都将其设置在中GlobalAuthenticationConfigurerAdapter,例如,它看起来像是您的内部类SimpleEmbeddedSecurityConfiguration

@Configuration
public static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter
{
    @Bean(name = Global.AUTHENTICATION_DATA_QUALIFIER + "DataSource")
    public DataSource dataSource()
    {
        return new EmbeddedDatabaseBuilder().setName("authdb").setType(EmbeddedDatabaseType.H2).addScripts("security/schema.sql", "security/data.sql").build();
    }

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception
    {
            auth.jdbcAuthentication().dataSource(dataSource()).passwordEncoder(passwordEncoder());
    }
}

如果您不使用,GlobalAuthenticationConfigurerAdapter那么DataSource在创建安全性过滤器时(@Primary
DataSource甚至在bean尚未注册之前),Spring Data
REST就会获取这些获取的内容,并且整个JPA初始化会非常早地开始(不好的主意)。

更新:身份验证管理器不是唯一的问题。如果您需要进行会话范围的操作@Primary
DataSource(我会说这很不寻常),则需要在启动时关闭所有需要访问数据库的内容(Hibernate和Spring Boot在各个地方)。例:

spring.datasource.initialize: false
spring.jpa.hibernate.ddlAuto: none
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults: false
spring.jpa.properties.hibernate.dialect: H2

进一步更新:如果您使用的是执行器,它还希望在启动时将主要数据源用于运行状况指示器。您可以通过私有相同类型的bean来覆盖它,例如

@Bean
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
@Lazy
public DataSourcePublicMetrics dataSourcePublicMetrics() {
    return new DataSourcePublicMetrics();
}

PS我相信GlobalAuthenticationConfigurerAdapter在Spring Boot
1.2.2中可能并不需要,但在1.2.1或1.1.10中是必需的。

2020-11-30