Spring Boot与基于会话的数据源

时间:2015-02-19 15:35:04

标签: java spring spring-boot spring-data-rest

我一直在用一个Web应用程序的常见用例来撕掉我的头发。我有一个Spring-Boot应用程序,它使用REST存储库,JPA等。问题是我有两个数据源:

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

由于第二个数据源特定于经过身份验证的用户,因此我尝试使用AbstractRoutingDataSource根据Principal用户在身份验证后路由到正确的数据源。

让我疯狂的是,Spring-Boot正在激励我在启动时实例化这个数据源。我已经尝试了我能想到的一切,包括Lazy和Scope注释。如果我使用会话范围,则应用程序会抛出有关启动时不存在会话的错误。 @Lazy似乎没有任何帮助。无论我使用什么注释,数据库都是在Spring Boot启动时实例化的,并且没有找到任何基本上崩溃整个应用程序的查找键。

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

非常感谢任何建议。

1 个答案:

答案 0 :(得分: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之前,Spring {0}会获取DataSource bean甚至已被注册)并且整个JPA初始化开始超级早期(坏主意)。

更新:身份验证管理器不是唯一的问题。如果你需要一个会话作用域@Primary DataSource(我说不太常见),你需要在启动时关闭所有想要访问数据库的东西(Hibernate和Spring Boot in各个地方)。例如:

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

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

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

P.S。我相信在Spring Boot 1.2.2中可能不需要GlobalAuthenticationConfigurerAdapter,但它在1.2.1或1.1.10中。