带有注解@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;
}
}
}
我有一个存储库接口和两个 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;
}
}
}