在阅读Spring Data文档时,我多次遇到@NoRepositoryBean
接口。
引用文档:
如果您正在使用自动存储库接口检测 使用接口的Spring命名空间将导致Spring 试图创建一个MyRepository实例。这当然不是 因为它只是在Repository和the之间起作用 您要为每个实体定义的实际存储库接口。至 排除扩展Repository的实例化的接口 存储库实例使用
@NoRepositoryBean
注释它。
但是,我仍然不确定何时何地使用它。有人可以建议并给我一个具体的用法示例吗?
答案 0 :(得分:110)
注释用于避免为实际匹配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实例的候选者。
答案 1 :(得分:0)
我们可以声明一个新接口作为我们的自定义方法:
@NoRepositoryBean
public interface ExtendedRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
List<T> findByAttributeContainsText(String attributeName, String text);
}
我们的接口扩展了JpaRepository接口,因此我们将从所有标准行为中受益。
您还将注意到我们添加了@NoRepositoryBean批注。这是必要的,因为否则,Spring的默认行为是为存储库的所有子接口创建一个实现。
public interface ExtendedStudentRepository extends ExtendedRepository<Student, Long> {
}