我想用自定义实现扩展JpaRepository
,所以我添加了一个MyRepositoryCustom
接口和一个扩展此接口的MyRepositoryImpl
类。
有没有办法在我的自定义类中调用JpaRepository
的方法?
注意:这也被问及对https://stackoverflow.com/a/11881203/40064的评论,但我认为这应该是一个单独的问题。
答案 0 :(得分:13)
要将核心存储库接口注入自定义实现,请将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为该依赖创建一个延迟初始化的代理,即使它首先为MyRepository
创建一个实例。在自定义方法的实现中,您可以使用….get()
- 方法访问实际的bean。
Provider
是来自@Inject
JSR的接口,因此是标准化接口,需要对该API JAR的额外依赖。如果你只想坚持使用Spring,你可以使用ObjectFactory
作为替代接口但是会得到相同的行为。
答案 1 :(得分:1)
文档中标题为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
调用。