自定义 spring-session 存储库 Redis with Dynomite

Custom spring-session repository Redis with Dynomite

在我们的基础架构中,我们将 Redis 与 Dynomite 结合使用以实现数据中心复制和高可用性。 我们的一个应用程序在 Java 中,我们主要使用 spring 生态系统。

在这个应用程序中,我们使用 spring-session 管理会话,我们使用 Redis 集群来存储会话。

Spring 会话正在使用 Dynomite 上下文中不允许的 pub/sub 命令,因此我们需要自定义存储库。

我尝试这样做,但我遇到了 spring-引导和自动配置 class 的问题。

请在下面找到我们代码的一部分。

build.gradle

中的依赖项
val springBootVersion = "2.1.4.RELEASE"
val springSessionDataRedisVersion = "2.1.5.RELEASE"

implementation("org.springframework.boot:spring-boot-starter-security:$springBootVersion")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion")
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
implementation("org.springframework.boot:spring-boot-starter-data-redis:$springBootVersion")
implementation("org.springframework.session:spring-session-data-redis:$springSessionDataRedisVersion")

我们的配置 class 用我们自定义的覆盖 sessionRepository

@Configuration
@EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer     {

@Bean
public SessionRepository sessionRepository() {
    return new RedisDynoSessionRepository();
    }
}

sessionRepository自定义class

public class RedisDynoSessionRepository implements SessionRepository {
...
}

当我们 运行 我们的应用程序时,我们在 bean 中发生冲突,因为应用程序发现 bean 会话存储库已知。

org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'sessionRepository' defined in class path resource [com/orange/ccmd/spring/redis/SessionConfig.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=sessionConfig; factoryMethodName=sessionRepository; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/orange/ccmd/spring/redis/SessionConfig.class]] for bean 'sessionRepository': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration; factoryMethodName=sessionRepository; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]] bound.

我正在寻找绕过这个问题的方法可能是取消注册 bean?

谢谢你的帮助。


[编辑]

我在 bean 上尝试了 @Primary,但它不起作用。 如果我以不同的方式命名我的 bean,Spring 使用标准 bean 而不是我自定义的新 bean。 如果我以相同的方式命名它,则会出现冲突错误。 如果我放置覆盖 bean 配置 (spring.main.allow-bean-definition-overriding=true),我会出错,因为这 2 个 bean 的类型不同。这是我打算做的,因为我不想在我的回购协议中使用消息传递的东西。

我在 github Spring-session repo (https://github.com/spring-projects/spring-session/issues/1406) 上开了一个问题。

我得到了答案。事实上,我做错了。正如文档中所述。我必须使用 @EnableSpringHttpSession 注释来注册我的自定义 bean 而不是 @EnableRedisHttpSession.

它有效,我在应用程序初始化期间没有遇到任何问题。