当前位置: 首页 > 知识库问答 >
问题:

带有基于会话的数据源的Spring Boot

闻人浩波
2023-03-14

我一直在为Web应用程序的一个非常常见的用例而烦恼。我有一个使用REST存储库、JPA等的Spring-Boot应用程序。问题是我有两个数据源:

  • 包含用户身份验证信息的嵌入式H2数据源

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

让我抓狂的是,Spring Boot在启动时拼命地让我实例化这个数据源。我已经尝试了我能想到的一切,包括懒惰和范围注释。如果使用会话作用域,则应用程序会在启动时抛出一个关于不存在会话的错误@懒惰似乎一点帮助都没有。无论我使用什么注释,数据库都是在Spring Boot启动时实例化的,并且找不到任何导致整个应用程序崩溃的查找键。

另一个问题是Rest Repository API在指定要使用的实际数据源方面有一种糟糕的方法。如果您使用Spring Boot有多个数据源,则必须同时处理限定符注释,这是运行时调试的噩梦。

任何建议都将非常感谢。

共有1个答案

万俟小林
2023-03-14

您的问题是身份验证管理器配置。所有示例和指南都在GlobalAuthenticationConfigurerAdapter中设置了此选项,例如,它看起来像是SimpleEmbeddedSecurity配置的内部类:

@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());
    }
}

如果不使用globalaauthenticationconfigureradapter,那么在创建安全过滤器的过程中(甚至在注册主数据源bean之前),Spring数据REST会提取数据源,并且整个JPA初始化会很早开始(坏主意)。

更新:身份验证管理器不是唯一的问题。如果您需要将会话范围限定为主数据源(我认为这很不寻常),那么您需要在启动时关闭所有需要访问数据库的东西(在不同的地方使用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();
}

附言:我相信GlobalAuthentiationConfigrerAdapter在Spring Boot 1.2.2中可能不需要,但它在1.2.1或1.1.10中是必要的。

 类似资料:
  • 问题内容: 我一直在整理应该是Web应用程序的一个非常常见的用例。我有一个使用REST信息库,JPA等的Spring-Boot应用程序。问题是我有两个数据源: 包含用户身份验证信息的嵌入式H2数据源 MySQL数据源,用于特定于已验证用户的实际数据 因为第二个数据源是特定于已验证用户的,所以我尝试使用AbstractRoutingDataSource根据验证后的主要用户路由到正确的数据源。 绝对让

  • 问题内容: 我一直在整理应该是Web应用程序的一个非常常见的用例。我有一个使用REST信息库,JPA等的Spring-Boot应用程序。问题是我有两个数据源: 包含用户身份验证信息的嵌入式H2数据源 MySQL数据源,用于特定于已验证用户的实际数据 因为第二个数据源是特定于已验证用户的,所以我尝试使用AbstractRoutingDataSource根据验证后的主要用户路由到正确的数据源。 绝对让

  • 我的jsp页面可以通过以下方式访问bean: 如果我将作用域更改为“request”,tomcat会抛出一个异常:javax。servlet。ServletException:java。lang.InstanceException:在范围内找不到bean myBean 但我通过从servlet转发来访问jsp页面,如下所示: 我认为上述转发会导致MyJsp.jsp继承原始servlet的请求对象,

  • 我正在将Spring 4与Hibernate 4一起使用,并尝试配置多个数据源。当我使用新的第二个时,我总是收到错误。 异常org . spring framework . web . util . nestedservletexception:请求处理失败;嵌套异常为org . hibernate . hibernate exception:未找到当前线程的会话org . spring fram

  • 我正在尝试在Heroku上部署我的Quarkus-app。它工作正常,但我需要使用固定值指定数据源参数。因为Heroku可能会旋转此参数,所以这不是一个真正的好主意。 在Quarkus中,我需要应用程序中的这3个参数。属性: Heroku只给了我1个环境变量(

  • 我有一个Azure Logic应用程序,当一个或多个消息到达队列(peek lock)连接器时,它会处理来自基于服务总线会话的队列的消息。 我已经向服务总线队列发送了20条具有相同会话id的消息。 但它并不是一次读取所有消息。它正在一个接一个地阅读。 我关注了这些链接 https://docs.microsoft.com/en-us/connectors/servicebus/#when-一条或多