Skip to content

Support disabling of redis autoconfiguration via config property. #4678

New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants