了解 Spring Data JPA @NoRepositoryBean 接口
Posted
技术标签:
【中文标题】了解 Spring Data JPA @NoRepositoryBean 接口【英文标题】:Understanding the Spring Data JPA @NoRepositoryBean interface 【发布时间】:2012-07-19 13:57:26 【问题描述】:我在阅读 Spring Data 文档时多次遇到@NoRepositoryBean
接口。
引用文档:
如果您使用自动存储库接口检测,则使用 使用接口的 Spring 命名空间原样会导致 Spring 试图创建 MyRepository 的实例。这当然不是 需要,因为它只是充当存储库和 您要为每个实体定义的实际存储库接口。到 排除扩展存储库的接口被实例化为 存储库实例用
@NoRepositoryBean
注释它。
但是,我仍然不确定何时何地使用它。有人可以建议并给我一个具体的用法示例吗?
【问题讨论】:
【参考方案1】:注解用于避免为实际上符合 repo 接口标准但不打算成为一个标准的接口创建存储库代理。仅当您开始使用功能扩展所有存储库时才需要它。举个例子吧:
假设您想将方法 foo() 添加到所有存储库。您可以从添加这样的 repo 接口开始
public interface com.foobar.MyBaseInterface<…,…> extends CrudRepository<…,…>
void foo();
您还可以添加相应的实现类、工厂等。您的具体存储库接口现在将扩展该中间接口:
public interface com.foobar.CustomerRepository extends MyBaseInterface<Customer, Long>
现在假设您引导 - 比如说 Spring Data JPA - 如下:
<jpa:repositories base-package="com.foobar" />
您使用com.foobar
是因为您在同一个包中拥有CustomerRepository
。 Spring Data 基础设施现在无法判断 MyBaseRepository
不是具体的存储库接口,而是充当中间存储库以公开附加方法。所以它会尝试为它创建一个存储库代理实例并失败。您现在可以使用@NoRepositoryBean
来注释这个中间接口,本质上告诉 Spring Data:不要为这个接口创建存储库代理 bean。
这种情况也是CrudRepository
和PagingAndSortingRepository
也带有这个注解的原因。如果包扫描偶然发现了这些(因为您不小心以这种方式配置了它),则引导程序将失败。
长话短说:使用注释来防止存储库接口被选为候选最终成为存储库 bean 实例。
【讨论】:
【参考方案2】:我们可以声明一个新接口作为我们的自定义方法:
@NoRepositoryBean
public interface ExtendedRepository<T, ID extends Serializable> extends JpaRepository<T, ID>
List<T> findByAttributeContainsText(String attributeName, String text);
我们的接口扩展了 JpaRepository 接口,因此我们将从所有标准行为中受益。
您还会注意到我们添加了@NoRepositoryBean 注释。这是必要的,否则,默认的 Spring 行为是为 Repository 的所有子接口创建一个实现。
public interface ExtendedStudentRepository extends ExtendedRepository<Student, Long>
【讨论】:
以上是关于了解 Spring Data JPA @NoRepositoryBean 接口的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Spring Data JPA 了解底层数据库名称