Allow application to extends those configurations mitigate gh-27834
for example I have two redis services, the default one is @Primary, the global one must be injected with prefix global in @Qualifier
@Primary
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class DefaultRedisProperties extends RedisProperties {
}
@Configuration(proxyBeanMethods = false)
public class DefaultConnectionConfiguration extends LettuceConnectionConfiguration {
    DefaultConnectionConfiguration(RedisProperties properties,
            ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
            ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) {
        super(properties, sentinelConfigurationProvider, clusterConfigurationProvider);
    }
    @Primary
    @Bean(destroyMethod = "shutdown")
    public DefaultClientResources lettuceClientResources() {
        return super.lettuceClientResources();
    }
    @Primary
    @Bean
    public LettuceConnectionFactory redisConnectionFactory(
            ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
            ClientResources globalLettuceClientResources) {
        return super.redisConnectionFactory(builderCustomizers, globalLettuceClientResources);
    }
}
@Configuration(proxyBeanMethods = false)
public class DefaultRedisConfiguration {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }
}
@Component
@ConfigurationProperties(prefix = "global.redis")
public class GlobalRedisProperties extends RedisProperties {
}
@Configuration(proxyBeanMethods = false)
public class GlobalConnectionConfiguration extends LettuceConnectionConfiguration {
    GlobalConnectionConfiguration(GlobalRedisProperties properties,
            ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
            ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) {
        super(properties, sentinelConfigurationProvider, clusterConfigurationProvider);
    }
    @Bean(destroyMethod = "shutdown")
    DefaultClientResources globalLettuceClientResources() {
        return super.lettuceClientResources();
    }
    @Bean
    LettuceConnectionFactory globalRedisConnectionFactory(
            ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
            @Qualifier("globalLettuceClientResources") ClientResources globalLettuceClientResources) {
        return super.redisConnectionFactory(builderCustomizers, globalLettuceClientResources);
    }
}
@Configuration(proxyBeanMethods = false)
public class GlobalRedisConfiguration {
    @Bean
    public RedisTemplate<Object, Object> globalRedisTemplate(
            @Qualifier("globalRedisConnectionFactory") RedisConnectionFactory globalRedisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(globalRedisConnectionFactory);
        return template;
    }
    @Bean
    public StringRedisTemplate globalStringRedisTemplate(
            @Qualifier("globalRedisConnectionFactory") RedisConnectionFactory globalRedisConnectionFactory) {
        return new StringRedisTemplate(globalRedisConnectionFactory);
    }
}
Comment From: philwebb
We discussed this today on our team call and agreed that we'd rather keep those configurations package-private. You should duplicate the appropriate @Bean methods in your own @Configuration for complex setups.