Reputation: 461
In our infrastructure, we are using Redis with Dynomite to have a replication over datacenter and high availability. One of our app is in Java and we are mainly using spring ecosystem.
In this app, we manage session using spring-session and we use the Redis cluster to store the sessions.
Spring session is using pub/sub commands which are not allowed in a Dynomite context so we need to to a custom repository.
I tried to do so but I have an issue with spring-boot and autoconfiguration class.
please find below some part of our code.
dependencies in a 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")
Our configuration class to override the sessionRepository with our custom one
@Configuration
@EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
@Bean
public SessionRepository sessionRepository() {
return new RedisDynoSessionRepository();
}
}
The sessionRepository custom class
public class RedisDynoSessionRepository implements SessionRepository {
...
}
When we run our app, we a collision in the bean because the app finds that the bean session repository is already known.
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.
I am looking for a way to bypass this problem may be with unregistring the bean ?
Thanks for you help.
[EDIT]
I tried the @Primary on the bean and it doesn't work.
If I named my bean differently, Spring uses the standard bean not my custom new one.
If I named it the same way, I have a conflict error.
If I put the override bean configuration (spring.main.allow-bean-definition-overriding=true
), I have an error because the 2 beans don't have the same type. Which is what I intend to do because I don't want the messaging stuff in my repo.
Upvotes: 2
Views: 3850
Reputation: 461
I have opened an issue on the github Spring-sesssion repo (https://github.com/spring-projects/spring-session/issues/1406).
I had my answer. In fact, I did it the wrong way. As it is stated in the documentation. I have to use the @EnableSpringHttpSession
annotation to register my custom bean instead of the @EnableRedisHttpSession
.
And it works, I don't have any issue during the app initialization.
Upvotes: 2