我的自定义存储库实现中的CrudRepository

我试图获得对我的存储库接口( UserRepository )的引用,该接口在我的自定义实现( UserRepositoryExtensionImpl )中扩展CrudRepository ,以便获得对Spring JPA提供的所有方法的访问。

Crud扩展:

 @Repository public interface UserRepository extends CrudRepository, UserRepositoryExtension { ...any custom spring JPA methods... } 

扩展接口:

 @Repository public interface UserRepositoryExtension  { public T put(T entity); } 

定制实施:

 public class UserRepositoryExtensionImpl implements UserRepositoryExtension { UserRepository userRepository; @Autowired public UserRepositoryExtensionImpl(UserRepository userRepository) { this.userRepository = userRepository; } @Override public User put(User user) { System.out.println(user + "was put"); // ...put logic here return null; }... } 

但是,我无法注入UserRepository因为存在循环依赖(假设UserRepository扩展了我的UserRepositoryImpl实现的接口)。 我收到以下错误:

 org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ' userRepositoryImpl': Requested bean is currently in creation: Is there an unresolvable circular reference? 

一个可能但不太理想的解决方案是将EntityManager注入UserRepositoryImp ,但在这种情况下,我无法访问CrudRepository提供的任何Spring JPA方法,或者我可能在UserRepository中创建的任何其他方法。

关于如何解决这个问题的任何建议?

任何帮助将不胜感激。

编辑:正如在@ Shelley的回答中提到的,我能够通过进行3次更改来解决这个问题:

  • UserRepositoryExtensionImpl删除UserRepositoryExtensionImpl
  • UserRepositoryExtensionImpl重命名为UserRepositoryImpl 。 显然,这使得Spring意识到实现的存在。 见Spring Doc
  • 删除我的构造函数并将@Autowired移动到userRepository字段

成功!

为了实现这一点,需要更改几件小事:

  • 从自定义存储库接口( UserRepositoryExtension )中删除UserRepositoryExtension

  • 自定义存储库实现实际上应该命名为“ Impl ”而不是“ Impl ”。 在您的代码示例中,这应该是UserRepositoryImpl而不是UserRepositoryExtensionImpl

正如Shelley指出的那样,命名对于使autowire工作非常重要。 在下面的示例中,我遵循自定义界面及其实现的正确命名标准。 但我扩展JpaRepository的界面被命名为“ItemDao”而不是“ItemRepository”,这导致Spring完全忽略了我的自定义实现……

OBS! 应该是“ItemRepository”

 @Repository public interface ItemDao extends JpaRepository, ItemRepositoryCustom {} 

我的界面

 interface ItemRepositoryCustom {...} 

我的实现类

 class ItemRepositoryImpl implements ItemRepositoryCustom {...} 

如果有人遇到类似问题,请首先遵循以下链接中弹簧文档中使用的命名标准。

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations

有一种明确定义的方法可以在Spring Data JPA中创建自定义存储库实现 ,您应该遵循这些方法。 基本上你需要扩展CrudRepository这样你就不必在自定义实现中注入它的实例。

我通过使用applicationContext.getBean(UserRepository.class)注入ApplicationContext并以懒惰方式获取bean来解决问题。 它以这种方式工作。

我找到了如何在不需要@Autowire情况下做到这一点:

 public interface UserRepository extends UserRepositoryBasic, UserRepositoryExtension { } public interface UserRepositoryBasic extends JpaRepository { // standard Spring Data methods, like findByLogin } public interface UserRepositoryExtension { public void customMethod(); } public class UserRepositoryExtensionImpl implements UserRepositoryExtension { private final UserRepositoryBasic userRepositoryBasic; // constructor-based injection public UserRepositoryExtensionImpl( UserRepositoryBasic userRepositoryBasic) { this.userRepositoryBasic = userRepositoryBasic; } public void customMethod() { // we can call all basic Spring Data methods using // userRepositoryBasic } }