spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.21k stars 40.7k forks source link

Bug report: LettuceConnectionConfiguration #41465

Closed YiiGaa closed 4 months ago

YiiGaa commented 4 months ago

Springboot version: 3.3.1

I want to connect multiple redis on springboot, and I have defined a custom prefix for creating my own LettuceConnectionFactory :

    @ConfigurationProperties(prefix = "module.sr-opersession.redis")
    @Bean(name = "Module_OperSession.ConnectConfig")
    public RedisProperties _OperSessionConnectConfig() {
        return new RedisProperties();
    }

But when running springboot, there is an error.

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration required a single bean, but 2 were found:
        - Module_OperSession.ConnectConfig: defined by method '_OperSessionConnectConfig' in class path resource [com/stoprefactoring/once/module/_OperSession/_OperSessionRedis.class]
        - spring.data.redis-org.springframework.boot.autoconfigure.data.redis.RedisProperties: defined in unknown location

The reason is that org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration automatically uses RedisProperties.

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisClient.class)
@ConditionalOnProperty(name = "spring.data.redis.client-type", havingValue = "lettuce", matchIfMissing = true)
class LettuceConnectionConfiguration extends RedisConnectionConfiguration {

    LettuceConnectionConfiguration(RedisProperties properties,
            ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
            ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
            ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider,
            RedisConnectionDetails connectionDetails, ObjectProvider<SslBundles> sslBundles)         {...}
...
}

And the spring.data.redis-org.springframework.boot.autoconfigure.data.redis.RedisProperties defined like this:

@ConfigurationProperties(prefix = "spring.data.redis")
public class RedisProperties {
...
}

I think spring.data.redis-org.springframework.boot.autoconfigure.data.redis.RedisProperties should add @Primary

or LettuceConnectionConfiguration change the setting of @ConditionalOnProperty or LettuceConnectionConfiguration add @Qualifier for RedisProperties properties

wilkinsona commented 4 months ago

I'm afraid that we don't consider this to be a bug. There are many places in Spring Boot where we inject a …Properties class and expect there to be a single candidate. We also don't consider the …Properties classes to be public API:

The properties that map to @ConfigurationProperties classes available in Spring Boot, which are configured through properties files, YAML files, environment variables, and other mechanisms, are public API but the accessors (getters/setters) of the class itself are not meant to be used directly.

You should define your own @ConfigurationProperties class that meets your specific needs.

We hope to improve support for auto-configuring multiple beans, such as multiple Redis connections in the future. Please see #22403 and #15732 for details.