Spring Boot集成Aerospike缓存与Redis时的配置报错问题
Spring Boot同时集成Redis与Aerospike时的缓存Bean冲突问题
我需要在Spring Boot中同时使用Redis和Aerospike:用Aerospike实现Spring缓存功能,Redis仅作为单值读取的CRUD Repository使用。但配置Aerospike缓存管理时触发Bean冲突错误,根源是Redis的默认配置导致的。当前使用Spring Boot 3.2.1、spring-data-aerospike 4.8.0版本,尝试过@Qualifier、@Primary注解但无效。
Aerospike配置类
@Configuration @EnableConfigurationProperties(AerospikeProperties.class) @EnableAerospikeRepositories(basePackageClasses = {CacheableFileEntityRepository.class}) public class AerospikeConfig extends AbstractAerospikeDataConfiguration { @Autowired private AerospikeProperties aerospikeProperties; @Override protected Collection<Host> getHosts() { return aerospikeProperties.getHosts() ; } @Override protected String nameSpace() { return aerospikeProperties.getNamespace(); } }
Aerospike属性类
@Log4j2 @Data @Profile("aerospike") @ConfigurationProperties(prefix = "aerospike") @RequiredArgsConstructor(onConstructor_ ={@Autowired}) public class AerospikeProperties { @Value("${spring.aerospike.host}") private String host; @Value("${spring.aerospike.port}") private int port; @Value("${spring.aerospike.namespace}") private String namespace; @Value("${spring.aerospike.policies.client.readTimeout}") private int readTimeout; @Value("${spring.aerospike.policies.client.writeTimeout}") private int writeTimeout; @Value("${spring.aerospike.policies.client.connectionTimeout}") private int connectionTimeout; @Value("${spring.aerospike.policies.client.maxSocketIdle}") private int maxSocketIdle; @Value("${spring.aerospike.policies.client.totalTimeout}") private int totalTimeout; @Bean(destroyMethod = "close") public AerospikeClient aerospikeClient() { try { ClientPolicy clientPolicy = new ClientPolicy(); clientPolicy.readPolicyDefault.replica = Replica.MASTER; clientPolicy.readPolicyDefault.readModeAP = ReadModeAP.ONE; clientPolicy.writePolicyDefault.commitLevel = CommitLevel.COMMIT_ALL; clientPolicy.readPolicyDefault.socketTimeout = readTimeout; clientPolicy.readPolicyDefault.totalTimeout = totalTimeout; clientPolicy.writePolicyDefault.socketTimeout = writeTimeout; clientPolicy.writePolicyDefault.totalTimeout = totalTimeout; clientPolicy.maxSocketIdle=maxSocketIdle; clientPolicy.timeout=connectionTimeout; return new AerospikeClient(clientPolicy, host, port); } catch (RuntimeException e) { return null; } } protected Collection<Host> getHosts() { return Collections.singleton(new Host(host, port)); } protected String getNamespace() { return namespace; } }
触发错误的AerospikeCacheManager配置
添加以下Bean配置时触发错误:
@Bean public AerospikeCacheManager cacheManager(AerospikeClient aerospikeClient) { AerospikeCacheConfiguration defaultConfiguration = new AerospikeCacheConfiguration("tax_registration"); return new AerospikeCacheManager(aerospikeClient, mappingAerospikeConverter, defaultConfiguration); }
错误信息
Parameter 1 of constructor in org.springframework.data.aerospike.convert.MappingAerospikeConverter required a single bean, but 2 were found: - org.springframework.data.aerospike.convert.AerospikeCustomConversions: defined in unknown location - redisCustomConversions: defined in unknown location
解决方法
问题源于Spring Data中Redis和Aerospike各自生成的CustomConversions Bean冲突,导致MappingAerospikeConverter无法确定依赖哪一个实例。可以通过以下步骤解决:
- 显式声明Aerospike的MappingAerospikeConverter Bean,指定使用Aerospike专属的
AerospikeCustomConversions:
@Bean public MappingAerospikeConverter mappingAerospikeConverter(AerospikeCustomConversions aerospikeCustomConversions, AerospikeMappingContext aerospikeMappingContext) { return new MappingAerospikeConverter(aerospikeMappingContext, aerospikeCustomConversions); }
- 修改AerospikeCacheManager的Bean定义,注入上面显式创建的转换器:
@Bean public AerospikeCacheManager cacheManager(AerospikeClient aerospikeClient, MappingAerospikeConverter mappingAerospikeConverter) { AerospikeCacheConfiguration defaultConfiguration = new AerospikeCacheConfiguration("tax_registration"); return new AerospikeCacheManager(aerospikeClient, mappingAerospikeConverter, defaultConfiguration); }
- 排查潜在的客户端Bean冲突:
AerospikeProperties中定义的AerospikeClientBean与AbstractAerospikeDataConfiguration自动生成的客户端实例可能冲突,建议移除AerospikeProperties中的aerospikeClient()方法,由AbstractAerospikeDataConfiguration统一管理客户端;如果需要保留自定义配置,可在其中一个Bean上添加@Primary注解指定优先实例。
内容的提问来源于stack exchange,提问作者Mohammad mahdi Esmaeili
相关产品推荐
相关产品推荐

