在 Spring Boot 中对两个存储库使用 mongo 和 redis 缓存

Using mongo and redis cache with both repositories in Spring Boot

我想同时使用 Redis 和 Mongo 存储库方式(我不想使用 spring 缓存注释,而是存储库方法)。

我用下面的注释对主要 class 进行了注释。

@EnableMongoRepositories(basePackageClass = PersistencyRepository.class)
@EnableRedisRepositories(basePackageClass = CacheRepository.class)
@SpringBootApplication

回购

public interface PersistencyRepository extends CrudRepository<Store, String> {}

public interface CacheRepository extends MongoRepository<Store, String> {}

现在,我收到以下错误。

The bean "cacheRepository" defined in com.repository.CacheRepository defined in @EnableMongoRepositories declared on StoreApplication, could not be registered. A bean with that name has already been defined in com.repository.CacheRepository defined in @EnableRedisRepositories declared on StoreApplication and overriding is disabled. 

如何使用 differenet 数据库(mongo、redis)的 repos?

您在 CacheRepository 上扩展了错误的存储库接口 (MongoRepository),请尝试扩展 CrudRepository。

另外,你的 mongo 和 redis 实体应该分开到不同的包中,通常我只是用 com.my.company.entity.mongo 和 com.my.company.entity.redis 每个。

之后,您需要更新那些配置注释。更好的包设计不是将所有注释放在 Main 上,而是将它们放在单独的包中,然后将这些注释放在那里。这有一个额外的好处,可以清楚地拆分每个配置的实际作用

例如:

package com.your.company.configuration;

import com.your.company.configuration.properties.ApplicationProperties;
import com.your.company.entity.mongo.BaseDocument;
import com.your.company.entity.postgres.BaseEntity;
import com.your.company.entity.redis.BaseHash;
import com.your.company.repository.mongo.BaseMongoRepository;
import com.your.company.repository.postgres.BaseJpaRepository;
import com.your.company.repository.redis.BaseRedisRepository;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableConfigurationProperties(ApplicationProperties.class)
@EnableJpaRepositories(basePackageClasses = {BaseEntity.class, BaseJpaRepository.class})
@EnableMongoRepositories(basePackageClasses = {BaseDocument.class,
        BaseMongoRepository.class}, repositoryFactoryBeanClass = EnhancedMongoRepositoryFactoryBean.class)
@EnableRedisRepositories(basePackageClasses = {BaseHash.class, BaseRedisRepository.class})
public class BasicConfiguration {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

以上只是一个例子,通常我会将它们进一步拆分成一个class,每个都在同一个包中,名称描述它们实际配置的内容,例如:MongoConfiguration.java,JpaConfiguration.java,等等。请注意,如果您决定采用该设计,则需要在每个单独的 classes

中添加 @Configuration 注释

我认为这里的主要问题是您的接口 PersistencyRepositoryCacheRepository 都在同一个包中,并且您的配置都在同一个包中扫描 Spring 数据存储库接口,创建重复的 bean 名称。您应该将这些存储库分成它们自己的包。

重要的是要注意 basePackageClasses 扫描整个包以查找适用的接口。请参阅 EnableMongoRepositories.basePackageClasses (source) 的文档:

Type-safe alternative to basePackages() for specifying the packages to scan for annotated components. The package of each class specified will be scanned. Consider creating a special no-op marker class or interface in each package that serves no purpose other than being referenced by this attribute.