[spring-projects/spring-boot]@Qualifier DI 错误

2024-06-26 879 views
0

我通过 bean 名称定义它并使用 @Qulifier 注释。但它发送以下消息

@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;
    }
}

错误信息

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

回答

2

您正在使用哪个版本的 Spring Boot?

9

Spring Boot 2.5.0 版本

8
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()
}
5

该错误与自动配置类有关SessionRepositoryFilterConfiguration,该类需要单个RedisConnectionFactory或至少一个标记为 的类@Primary。错误不在于 2 个自定义类。中@Configuration命名的类可能需要标记为 ,或者在不需要时需要从自动配置中排除 。redisSessionConnectionFactoryRedisConfig@PrimarySessionRepositoryFilterConfiguration

1

我使用单独的 Redis 缓存服务器和单独的会话存储,还有其他方法吗?

9

您需要使用 标记 Spring Boot 应该使用的那个@Primary。我想知道我们应该做的是失败还是将条件更改为@ConditionalOnSingleCandidate

7

嗯,谢谢你的回复,但我希望我能把它写在 Spring Boot 文档里

6

您需要使用 标记 Spring Boot 应该使用的那个@Primary。我想知道我们应该做的是失败还是将条件更改为@ConditionalOnSingleCandidate

这将与其他数据存储驱动的配置更加一致(至少对于 JDBC/JPA 而言)。

8

故障分析确定的注入点不正确。故障实际上发生在 Spring Session 中,RedisHttpSessionConfiguration.setRedisConnectionFactory(ObjectProvider<RedisConnectionFactory>, ObjectProvider<RedisConnectionFactory>)它调用了getObject()第二个ObjectProvider<RedisConnectionFactory>。第一个注释为@SpringSessionRedisConnectionFactory,这开启了另一种解决问题的方法。

@cwangg897 您可以用注释您的redisSessionConnectionFactorybean 来@SpringSessionRedisConnectionFactory指示它是 Spring Session 应该使用的 Redis 连接工厂。Spring Session 参考文档中未提及该注释。我为此打开了https://github.com/spring-projects/spring-session/issues/2102 。

3

太感谢了

3

@ConditionalOnSingleCandidate由于注入点位于 Spring Session 中,因此我们无法修复此问题。希望https://github.com/spring-projects/spring-session/issues/2102能够被@SpringSessionRedisConnectionFactory记录下来。#31514 和 #31515 正在跟踪一些故障分析改进。我认为我们在这里无能为力。

8

如果 @SpringSessionRedisConnectionFactory 以注释的形式写在文档中,您能否告诉我?如果它写在文档中,其他人可以通过我获得帮助,所以我想保留它,因为我认为我贡献了 1%。谢谢,祝您有美好的一天