如何从自定义实现中引用 'normal' spring 数据存储库?

How to reference the 'normal' spring data repo from a custom implementation?

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

有没有办法在我的自定义 class 中调用 JpaRepository 的方法?

注意:这也作为对 的评论提出,但我认为它很常见,值得单独提问。

文档中标题为 Adding custom behaviour to all repositories 的部分应该对您有所帮助。

例如(仅供参考):

public interface ExtendedJpaRepository<T, ID extends Serializable>
       extends JpaRepository<T, ID> {
    T findFirst();
    T findLast();
}

public class ExtendedJpaRepositoryImpl<T, ID extends Serializable>
       extends SimpleJpaRepository<T, ID>
       implements ExtendedJpaRepository<T, ID> {
  public ExtendedJpaRepositoryImpl(Class<T> domainClass, EntityManager em) {
    super(domainClass, entityManager);
  }

  public T findFirst() {
    List<T> all = findAll();

    return !all.isEmpty() ? all.get(0) : null;
  }

  public T findLast() {
    List<T> all = findAll();

    return !all.isEmpty() ? all.get(all.size() - 1) : null;
  }
}

然后,根据上面链接的文档中给出的说明配置 ExtendedJpaRepositoryImpl 以供使用。

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

tl;博士

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

详情

实现该功能的核心挑战是正确设置依赖注入,因为您将要在要扩展的对象和扩展之间创建循环依赖。然而,这可以通过以下方式解决:

interface MyRepository extends Repository<DomainType, Long>, MyRepositoryCustom {
  // Query methods go here
}

interface MyRepositoryCustom {
  // Custom implementation method declarations go here
}

class MyRepositoryImpl implements MyRepositoryCustom {

  private final Provider<MyRepository> repository;

  @Autowired
  public MyRepositoryImpl(Provider<MyRepository> repository) {
    this.repository = repository;
  }

  // Implement custom methods here
}

这里最重要的部分是使用 Provider<MyRepository> 这将导致 Spring 为该依赖项创建延迟初始化的代理 即使它正在为 [=13 创建实例=]第一名。在自定义方法的实现中,您可以使用 ….get()-method.

访问实际的 bean

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