使用Dynomite的自定义spring-session存储库Redis

时间:2019-04-23 19:31:10

标签: java spring spring-boot spring-data-redis spring-session

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

在此应用中,我们使用spring-session管理会话,并使用Redis集群存储会话。

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

我尝试这样做,但是spring-boot和自动配置类存在问题。

请在下面的部分代码中查找。

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")

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

@Configuration
@EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer     {

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

sessionRepository自定义类

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没有相同的类型。我打算这样做是因为我不希望回购中包含消息内容。

1 个答案:

答案 0 :(得分:0)

我在github上的Spring-sesssion存储库(https://github.com/spring-projects/spring-session/issues/1406)上打开了一个问题。

我有我的答案。实际上,我做错了方法。如文档中所述。我必须使用@EnableSpringHttpSession批注而不是@EnableRedisHttpSession来注册我的自定义bean。

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