如何从自定义实现中引用“普通”spring数据仓库?

我想用自定义实现扩展JpaRepository ,所以我添加了一个MyRepositoryCustom接口和一个扩展此接口的MyRepositoryImpl类。

有没有办法从我的自定义类中的JpaRepository调用方法?

注意:这也是作为对https://stackoverflow.com/a/11881203/40064的评论而提出的,但我认为通常应该提出一个单独的问题。

TL;博士

要将核心存储库接口注入自定义实现,请将Provider注入自定义实现。

细节

实现这一目标的核心挑战是正确设置dependency injection,因为您要在要扩展的对象和扩展之间创建循环依赖关系。 但是,这可以解决如下:

 interface MyRepository extends Repository, MyRepositoryCustom { // Query methods go here } interface MyRepositoryCustom { // Custom implementation method declarations go here } class MyRepositoryImpl implements MyRepositoryCustom { private final Provider repository; @Autowired public MyRepositoryImpl(Provider repository) { this.repository = repository; } // Implement custom methods here } 

这里最重要的部分是使用Provider ,这将导致Spring为该依赖创建一个延迟初始化的代理, 即使它首先在为MyRepository创建实例时也是如此 。 在自定义方法的实现中,您可以使用….get() -method访问实际的bean。

Provider@Inject JSR的接口,因此是标准化接口,需要对该API JAR的额外依赖。 如果你只想坚持使用Spring,你可以使用ObjectFactory作为替代接口但是获得完全相同的行为。

标题为向文档中的所有存储库添加自定义行为的部分应该可以帮助您。

例如(仅用于说明目的):

 public interface ExtendedJpaRepository extends JpaRepository { T findFirst(); T findLast(); } public class ExtendedJpaRepositoryImpl extends SimpleJpaRepository implements ExtendedJpaRepository { public ExtendedJpaRepositoryImpl(Class domainClass, EntityManager em) { super(domainClass, entityManager); } public T findFirst() { List all = findAll(); return !all.isEmpty() ? all.get(0) : null; } public T findLast() { List all = findAll(); return !all.isEmpty() ? all.get(all.size() - 1) : null; } } 

然后,按照上面链接的文档中给出的说明配置ExtendedJpaRepositoryImpl

由于ExtendedJpaRepositoryImpl扩展了SimpleJpaRepository (它是SimpleJpaRepository的实现), JpaRepository可以从ExtendedJpaRepositoryImpl调用JpaRepository所有方法。