【问题标题】:How to retrieve spring data repository instance for given domain class?如何检索给定域类的弹簧数据存储库实例?
【发布时间】:2012-12-25 07:44:22
【问题描述】:
鉴于某个类Bar中所有spring数据存储库的列表:
@Autowired
private List<Repository> repositories;
如何在上述列表中找到现有域类 Foo 的存储库?
假设存在以下情况:
@Entity
public class Foo {
...
}
和
public interface FooRepository extends JpaRepository<Foo, String> {}
【问题讨论】:
标签:
java
spring
jpa
spring-data
spring-data-jpa
【解决方案1】:
Spring Data Commons 包含一个 Repositories 类,它采用 ListableBeanFactory 来查找其中定义的所有存储库 bean,并公开一个 API 以按域类(通过 ….getRepository(Class<?> type))获取这些实例。
应谨慎使用此类。由于存储库实例正在进行一些重要的代理生成,因此您必须确保在 ApplicationContext 创建期间尽可能晚地创建 Repositories 实例。首选方式是实现ApplicationListener,并通过监听ContextRefreshedEvent创建实例。
如果您正在编写 Web 应用程序,使用 Repositories 的最安全方法是引导由 ContextLoaderListener 创建的 ApplicationContext 中的存储库并将 Repositories 放置在Spring MVC 了解详情。
【解决方案2】:
@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);
}
}
【解决方案3】:
解决方案的关键是
Spring的org.springframework.data.repository.core.support.DefaultRepositoryMetadata,提供了getDomainType()的方法。
DefaultRepositoryMetadata 需要存储库接口作为构造函数 arg。因此可以遍历所有现有存储库,检索存储库接口(这仍然是一个棘手的部分,因为存储库实例有多个接口)并找到getDomainType()等于Foo.class 的那个。