Skip to content

Support disabling of redis autoconfiguration via config property. #4678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

sbuettner
Copy link

Currently you can only disable the redis autoconfiguration using the exclude property in the respective spring boot annotations like this @SpringBootApplication(exclude = RedisAutoConfiguration.class). This is needed if you have two redis connections (Spring Boots redis autoconfiguration expects a single bean). This PR introduces a single enabled flag that allows an application developer to control the autoconfiguration of redis more easily and in an environment dependent way.

Contribution agreement number: 133520150810110320

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 4, 2015
@snicoll
Copy link
Member

snicoll commented Dec 8, 2015

This is needed if you have two redis connections (Spring Boots redis autoconfiguration expects a single bean).

This looks fishy to me. What bean type are you talking about? (can you include a stacktrace?). IMO, if Spring Boot should auto-configure X and more than one bean of type X exists, it should just back-off.

@snicoll snicoll added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 8, 2015
@sbuettner
Copy link
Author

Here is the stacktrace after defining two JedisConnectionFactory beans:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.data.redis.connection.RedisConnectionFactory] is defined: expected single matching bean but found 2: oneRedisConnectionFactory,twoJedisConnectionFactory
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    ... 19 common frames omitted```

@wilkinsona
Copy link
Member

@sbuettner Can you show a bit more of the stacktrace, please? Specifically, it'd be useful to see which bean was being created when it couldn't find a unique bean.

@sbuettner
Copy link
Author

@wilkinsona Sure:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'redisTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration$RedisConfiguration.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.springframework.data.redis.connection.RedisConnectionFactory]: : No qualifying bean of type [org.springframework.data.redis.connection.RedisConnectionFactory] is defined: expected single matching bean but found 2:oneRedisConnectionFactory,twoJedisConnectionFactory; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.data.redis.connection.RedisConnectionFactory] is defined: expected single matching bean but found 2: oneRedisConnectionFactory,twoJedisConnectionFactory
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:838) ~[spring-context-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) ~[spring-context-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
    at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:347) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:295) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1112) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1101) [spring-boot-1.3.0.RELEASE.jar:1.3.0.RELEASE]

@sbuettner
Copy link
Author

@snicoll Nevertheless the flag might be useful when you just want to disable the autoconfiguration.

@snicoll
Copy link
Member

snicoll commented Dec 8, 2015

@sbuettner I am not denying that but I would do that consistently rather than adding enabled flags here and there.

@snicoll snicoll added for: team-attention An issue we'd like other members of the team to review and removed status: waiting-for-feedback We need additional information before we can continue labels Dec 8, 2015
@sbuettner
Copy link
Author

@snicoll ACK, the autoconfiguration part should work out of the box.

@snicoll
Copy link
Member

snicoll commented Dec 8, 2015

We have such issue in other areas. IMO, spring.redis.enabled=false while you're actually using it is a bit misleading. You should flag one of your JedisConnectionFactory as @Primary. If you don't want to do that, then excluding it is better IMO.

JMS and RabbitMQ have the exact same issue with JmsTemplate

@sbuettner
Copy link
Author

I didnt go with @Primary because it does not really reflect the fact that both JedisConnectionFactory are on the same "level" and using a custom property for the host for one and the default spring.redis.host property for the other connection didnt feel right because it would not be clear to other developers.

@snicoll snicoll removed the for: team-attention An issue we'd like other members of the team to review label Dec 9, 2015
@snicoll
Copy link
Member

snicoll commented Dec 9, 2015

We discussed this issue today and a enabled property is just syntactic sugar on excluding the auto-configuration (by class or by name). In any case, Boot should back off rather than forcing you to elect a @Primary candidate if you don't want to. This is covered in #2784.

@snicoll snicoll closed this Dec 9, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants