在我们的基础架构中,我们使用Redis与Dynomite进行数据中心复制和高可用性。我们的应用程序之一是Java,我们主要使用spring生态系统。
在这个应用程序中,我们使用spring-session管理会话,我们使用Redis集群来存储会话。
Spring会话使用的是pub / sub命令,这些命令在Dynomite上下文中是不允许的,因此我们需要使用自定义存储库。
我试图这样做,但我有一个spring-boot和autoconfiguration类的问题。
请在下面找到我们代码的部分内容。
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.
我正在寻找绕过这个问题的方法可能是用unregistring bean吗?
谢谢你的帮助。
[编辑]
我在bean上尝试了@Primary,它不起作用。如果我以不同的方式命名我的bean,Spring使用标准bean而不是我的自定义新bean。如果我以相同的方式命名它,我有一个冲突错误。如果我把覆盖bean配置(spring.main.allow-bean-definition-overriding=true
),我有一个错误,因为2个bean没有相同的类型。这是我打算做的,因为我不想在我的回购中发送消息。
我在github Spring-session repo(qazxsw poi)上打开了一个问题。
我得到了答案。事实上,我做错了。正如文档中所述。我必须使用https://github.com/spring-projects/spring-session/issues/1406annotation来注册我的自定义bean而不是@EnableSpringHttpSession
。
它有效,我在应用初始化期间没有任何问题。