带有注解@Primary 和@Secondary 的Spring Boot Bean 依赖注入

SpringBoot Bean dependency injection with annotation @Primary and @Secondary

我有一个存储库接口和两个 classes 实现它,一个是缓存存储库,另一个是 MongoDB 存储库。

public interface Repository {}

@Primary
@Component
public class CacheRepo implement Repository {}

@Component
public class MongoDBRepo implement Repository {}

获取项目的理想过程是使用缓存回购检查它是否存在于缓存中,如果不存在,请使用 MongoDB 回购,我的 [=] 上有一个 @Primary 12=] class 和依赖项在我的服务中注入 Repository 接口,但是如果在缓存中找不到项目,我怎么能仍然使用与 MongoDBRepo 相同的注入实例?有没有类似@Secondary的注释?

我建议你看看@Qualifier。使用它,您可以指定要注入哪个 Bean。为此,最好的选择是为每个 bean 定义一个组件名称,如下所示:

public interface Repository {}

@Component("cache")
public class CacheRepo implement Repository {}

@Component("mongodb")
public class MongoDBRepo implement Repository {}

然后,在另一个 Spring-managed bean 中,您可以按如下方式指定实现:

@Autowired
@Qualifier("mongodb")
private Repository mongoRepo;

您可以在 https://www.baeldung.com/spring-qualifier-annotation 阅读更多相关信息。

我认为你误解了 @Primary 的目的。
正如文档所说:

Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.

您可以在 MongoDBRepo 的方法上使用 @Cacheble 注释来执行您想要的操作,并定义自定义缓存管理器以使用您的 CacheRepo

这是对 @Cacheble 的有用介绍和一些示例 https://www.baeldung.com/spring-cache-tutorial

您要实现的是Repository Pattern

这里有一个简单的实现方法

public interface MyRepository {
  Optional<MyClass> findById(Long id);
}

那么你将有3个实现。这就是逻辑所在。

@Repository
@Qualifier("db")
public interface MyDbRepository extends MyRepository, CrudRepository<MyClass, Long>{
}

@Component
@Qualifier("cache")
public class MyCacheRepository implements MyRepository {
  public Optional<MyClass> findById(Long id){
    return Optional.empty();
  }
}

// This is the key
@Component
@Primary
public class MyDataSource implements MyRepository {

  @Autowire
  @Qualifier("db")
  private MyRepository dbRepo;

  @Autowire
  @Qualifier("cache")
  private MyRepository cacheRepo;

  public Optional<MyClass> findById(Long id){
    Optional<MyClass> myResponse = cacheRepo.findById(id);
    if(myResponse.isPresent()){
      return myResponse;
    } else {
      myResponse = dbRepo.findById(id);
      if(myResponse.isPresent){
        // Update your cache here
      }
      return myResponse;
    }
  }

}