[英]How to retrieve spring data repository instance for given domain class?
Given the list of all spring data repositories in some class Bar
:鉴于某些 class
Bar
中的所有 spring 数据存储库的列表:
@Autowired
private List<Repository> repositories;
How can I find the repository for an existing domain class Foo
in the above list?如何在上面的列表中找到现有域 class
Foo
的存储库?
Assuming that the following exists:假设存在以下情况:
@Entity
public class Foo {
...
}
and和
public interface FooRepository extends JpaRepository<Foo, String> {}
Spring Data Commons contains a class Repositories
that takes a ListableBeanFactory
to find all repository beans defined in it and exposes an API to obtain these instances by domain class (through ….getRepository(Class<?> type)
). Spring Data Commons包含一个类
Repositories
,它使ListableBeanFactory
查找在其中定义的所有存储库bean,并公开API以通过域类(通过….getRepository(Class<?> type)
)获取这些实例。
This class should be used with care. 应谨慎使用本课程。 As there's some serious proxy generation going on for the repository instances you have to make sure the
Repositories
instance is created as late as possible during the ApplicationContext
creation. 由于存储库实例正在进行一些严格的代理生成,因此必须确保在创建
ApplicationContext
期间尽可能晚地创建Repositories
实例。 The preferred way is to implement ApplicationListener
and create the instance by listening to the ContextRefreshedEvent
. 首选方法是实现
ApplicationListener
并通过侦听ContextRefreshedEvent
来创建实例。
In case you're writing a web application, the safest way to use Repositories
is by bootstrapping the repositories in the ApplicationContext
created by the ContextLoaderListener
and place the Repositories
(see the reference documentation of Spring MVC for details. 如果您正在编写Web应用程序,使用
Repositories
的最安全方法是引导ContextLoaderListener
创建的ApplicationContext
的Repositories
并放置Repositories
(有关详细信息,请参阅Spring MVC的参考文档) 。
@Service
public class GenericRepository {
@Autowired
private WebApplicationContext appContext;
Repositories repositories = null;
public GenericRepository() {
repositories = new Repositories(appContext);
}
public JpaRepository getRepository(AbstractPersistable entity) {
return (JpaRepository) repositories.getRepositoryFor(entity.getClass());
}
public Object save(AbstractPersistable entity) {
return getRepository(entity).save(entity);
}
public Object findAll(AbstractPersistable entity) {
return getRepository(entity).findAll();
}
public void delete(AbstractPersistable entity) {
getRepository(entity).delete(entity);
}
}
The key to the solution is Spring's org.springframework.data.repository.core.support.DefaultRepositoryMetadata
which provides the method getDomainType()
. 解决方案的关键是Spring的
org.springframework.data.repository.core.support.DefaultRepositoryMetadata
,它提供了方法getDomainType()
。
DefaultRepositoryMetadata
needs the repository interface as constructor arg. DefaultRepositoryMetadata
需要存储库接口作为构造函数arg。 So one can loop over all existing repositories, retrieve the repository interface (which is still a tricky part because the repository instance has more than one interface) and find the one where getDomainType()
equals Foo.class
. 因此,可以循环遍历所有现有存储库,检索存储库接口(这仍然是一个棘手的部分,因为存储库实例具有多个接口)并找到
getDomainType()
等于Foo.class
的存储库接口。
You can use Spring's GenericTypeResolver to get the Entity class from your Repository.您可以使用 Spring 的GenericTypeResolver从您的存储库中获取实体 class。
Repository<Foo, String> fooRepository = repositories.stream()
.filter(repository -> GenericTypeResolver
.resolveTypeArguments(repository.getClass(), Repository.class)[0].equals(Foo.class))
.findFirst().get();
This worked for me:这对我有用:
Repositories repositories = new Repositories(context);
CrudRepository repo = (CrudRepository) repositories.
getRepositoryFor(entityClass).get();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.