I defined it via bean name and used @Qulifier annotation. But it sends the following message

@Configuration
public class RedisConfig {

    @Value("${spring.redis.session.host}")
    private String host;

    @Value("${spring.redis.session.port}")
    private int sessionPort;

    @Bean(name = "redisSessionConnectionFactory")
    public RedisConnectionFactory redisSessionConnectionFactory() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName(host);
        configuration.setPort(sessionPort);
        return new LettuceConnectionFactory(configuration);
    }


    @Bean
    public RedisTemplate<String, Object> redisTemplate(@Qualifier(value = "redisSessionConnectionFactory") RedisConnectionFactory redisSessionConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setConnectionFactory(redisSessionConnectionFactory);
        return redisTemplate;
    }
}
@Configuration
public class CacheConfig {

    @Value("${spring.redis.cache.host}")
    private String cacheHost;

    @Value("${spring.redis.cache.port}")
    private int cachePort;

    @Bean(name = "redisCacheConnectionFactory")
    public RedisConnectionFactory redisCacheConnectionFactory() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName(cacheHost);
        configuration.setPort(cachePort);
        return new LettuceConnectionFactory(configuration);
    }

    @Bean
    public RedisCacheManager cacheManager(@Qualifier(value = "redisCacheConnectionFactory") RedisConnectionFactory redisCacheConnectionFactory) {

        RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        Map<String, RedisCacheConfiguration> redisCacheConfigMap = new HashMap<>();
        redisCacheConfigMap.put("board", defaultConfig.entryTtl(Duration.ofHours(1)));
        redisCacheConfigMap.put("user", defaultConfig.entryTtl(Duration.ofSeconds(30L)));

        RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisCacheConnectionFactory)
                .withInitialCacheConfigurations(redisCacheConfigMap)
                .build();

        return redisCacheManager;
    }
}

Error Message

Parameter 1 of method sessionRepositoryFilterRegistration in org.springframework.boot.autoconfigure.session.SessionRepositoryFilterConfiguration required a single bean, but 2 were found:
    - redisCacheConnectionFactory: defined by method 'redisCacheConnectionFactory' in class path resource [com/cwg/test/config/CacheConfig.class]
    - redisSessionConnectionFactory: defined by method 'redisSessionConnectionFactory' in class path resource [com/cwg/test/config/RedisConfig.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

Comment From: snicoll

What version of Spring Boot are you using?

Comment From: cwangg897

What version of Spring Boot are you using?

Spring Boot 2.5.0 version

Comment From: cwangg897

What version of Spring Boot are you using?

Spring Boot 2.5.0 version

plugins {
    id 'org.springframework.boot' version '2.5.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.cwg'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.2'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'mysql:mysql-connector-java'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    // spring에서 redis에 대한 의존성
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    // spring에서 redis를 session storage로 사용하기 위한 의존성
    implementation 'org.springframework.session:spring-session-data-redis'

}

tasks.named('test') {
    useJUnitPlatform()
}

Comment From: mdeinum

The error is about an autoconfiguration class SessionRepositoryFilterConfiguration which expects a single RedisConnectionFactory or at least one marked as @Primary. The error isn't on the 2 custom @Configuration classes. The one named redisSessionConnectionFactory in RedisConfig probably needs to be marked with @Primary or the SessionRepositoryFilterConfiguration needs to be excluded from the auto-configuration when not needed.

Comment From: cwangg897

The error is about an autoconfiguration class SessionRepositoryFilterConfiguration which expects a single RedisConnectionFactory or at least one marked as @Primary. The error isn't on the 2 custom @Configuration classes. The one named redisSessionConnectionFactory in RedisConfig probably needs to be marked with @Primary or the SessionRepositoryFilterConfiguration needs to be excluded from the auto-configuration when not needed.

I use a separate Redis cache server and a separate session store, is there any other way?

Comment From: snicoll

You need to mark the one that Spring Boot should use using @Primary. I wonder if failing is what we should be doing vs. changing the condition to @ConditionalOnSingleCandidate.

Comment From: cwangg897

Um Thank you Your Reply But I wish I could write it down in the Spring Boot documentation

Comment From: mdeinum

You need to mark the one that Spring Boot should use using @Primary. I wonder if failing is what we should be doing vs. changing the condition to @ConditionalOnSingleCandidate.

That would be more consistent with other datastore driven configuration (at least for JDBC/JPA).

Comment From: wilkinsona

I wonder if we should try to refine the action in the failure analysis as two of the three suggestions aren't possible due to the consumer being in Boot's own code. I've opened https://github.com/spring-projects/spring-boot/issues/31514.

Comment From: wilkinsona

The injection point identified by the failure analysis is incorrect. The failure's actually occurring in Spring Session's RedisHttpSessionConfiguration.setRedisConnectionFactory(ObjectProvider<RedisConnectionFactory>, ObjectProvider<RedisConnectionFactory>) where it's calling getObject() on the second ObjectProvider<RedisConnectionFactory>. The first is annotated with @SpringSessionRedisConnectionFactory which opens another way to fix the problem.

@cwangg897 You can annotate your redisSessionConnectionFactory bean with @SpringSessionRedisConnectionFactory to indicate that it's the Redis connection factory that Spring Session should use. The annotation isn't mentioned in the Spring Session reference documentation. I've opened https://github.com/spring-projects/spring-session/issues/2102 for that.

Comment From: cwangg897

Thank you so much

Comment From: wilkinsona

We can't fix this with @ConditionalOnSingleCandidate as the injection point is in Spring Session. https://github.com/spring-projects/spring-session/issues/2102 will hopefully result in @SpringSessionRedisConnectionFactory being documented. #31514 and #31515 are tracking some failure analysis improvements. I don't think there's anything more that we can do here.

Comment From: cwangg897

We can't fix this with @ConditionalOnSingleCandidate as the injection point is in Spring Session. spring-projects/spring-session#2102 will hopefully result in @SpringSessionRedisConnectionFactory being documented. #31514 and #31515 are tracking some failure analysis improvements. I don't think there's anything more that we can do here.

If @SpringSessionRedisConnectionFactory is written as a comment in the documentation, could you please let me know? If it is written in the document, other people can get help because of me, so I want to keep it because I think I contributed even 1%. Thank you, have a good day

Comment From: wilkinsona

If @SpringSessionRedisConnectionFactory is written as a comment in the documentation, could you please let me know?

Please subscribe to https://github.com/spring-projects/spring-session/issues/2102 for that.