大佬教程收集整理的这篇文章主要介绍了如何使用代理解析从 SimpleJpaRepository<T,ID> 对象取回存储库接口对象,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
存储库类
@Repository
public interface AllfileRepository extends JpaRepository<Allfile,Long> {
@query("SELECT a From Allfile a where a.guID = :guID")
Allfile findByGuID(@Param("guID") String guID);
}
服务类
@service
@Data
public class Pipelineservice implements serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@autowired
AllfileRepository allfileRepository;
}
创建对象 SimpleJpaRepository
Pipelineservice pipelineservice = new Pipelineservice();
void methodX() {
AnnotationConfigApplicationContext applicationContext = (AnnotationConfigApplicationContext)
ApplicationContextUtils.getApplicationContext();
AutowireCapableBeanFactory autowireCapableBeanFactory =
applicationContext.getAutowireCapableBeanFactory();
autowireCapableBeanFactory.autowireBean(pipelineservicE);
JpaRepository<AllFile,Long> jpaRepository = (SimpleJpaRepository<AllFile,Long>)
AopProxyUtils.getSingletonTarget(pipelineservice.getAllFileRepository());
// (AllFileRepository) jpaRepository casTing causes ClassCastException
}
异常
java.lang.ClassCastException: org.springframework.data.jpa.repository.support.SimpleJpaRepository cAnnot be cast to ....repository.AllFileRepository
如何获取 AllFileRepository 接口的对象?我可以在哪里访问 findByGuid("");
更新
我能够获得属于接口 AllFileRepository 的 SimpleJpaRepository<AllFile,Long>
对象,而后者又扩展了 JpaRepository
public void initialize() {
AnnotationConfigApplicationContext applicationContext = (AnnotationConfigApplicationContext) ApplicationContextUtils
.getApplicationContext();
Entitymanager em = applicationContext.getBean(Entitymanager.class);
AllFileRepository allFileRepository = new JpaRepositoryFactory(em).getRepository(AllFileRepository.class);
allFileRepository.findByGuid(""); // Method is accessible here but the object is proxy
SimpleJpaRepository<AllFile,Long> simpleJpaRepository = (SimpleJpaRepository<AllFile,Long>) (AopProxyUtils
.getSingletonTarget(allFileRepository)); // But proxy resolution yeilds SimpleJpaRepository cAnnot
// explicitly cast to AllFileRepository
((AllFileRepository) simpleJpaRepository).findByGuid(""); // class
// org.springframework.data.jpa.repository.support.SimpleJpaRepository
// cAnnot be cast to class
// com.example.spingaoprepository.repository.AllFileRepository
// (org.springframework.data.jpa.repository.support.SimpleJpaRepository
// and
// com.example.spingaoprepository.repository.AllFileRepository
// are in unnamed module of loader 'app'
}
这是示例 program
的链接您正在使用 new
关键字实例化 Pipelineservice,然后在您的 methodX() 中手动获取 Spring 上下文。
原则上,当然你“可以”在没有 Spring 的情况下手动完成所有操作。但是鉴于您的存储库和服务都是 Spring bean,那么最好让 Spring 处理 bean 生命周期。无论如何,这肯定更容易。
因为 Pipelineservice 是一个 Spring bean,所以你真的应该让任何使用它的类也知道 Spring。因此,只需使用 Spring 注释(如 @Component
、@service
或 @RestController
(如果它是控制器))来注释该类。
如果您坚持手动创建 bean,请尝试 -
ApplicationContext context = new AnnotationConfigApplicationContext();
Pipelineservice pipelineservice = context.getBean(Pipelineservice.class);
,
试图将不兼容的类型相互转换是没有用的。这不是 Spring 问题,而是 Java 基础知识。我也已经告诉过您如何在 Spring 中解决这个问题:您需要提供一个实际实现 AllFileRepository
的类,并确保 Spring Data JPA 将它用作存储库而不是接口。为此,您需要
@Repository
改为@NoRepositoryBean
,@Repository AllFileRepositoryImpl
并提供 AllFile findByGuid(String guid)
的实现,做一些有意义的事情。然后您可以轻松地以您想要的方式进行转换,因为您的代理的目标对象将是一个 AllFileRepositoryImpl
实例。
我向您发送了 pull request,您只需接受即可。相关 commit @5705cbb 中的类更改如下:
package com.example.spingaoprepository.repository;
import com.example.spingaoprepository.model.AllFile;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.repository.NoRepositoryBean;
@NoRepositoryBean
public interface AllFileRepository extends JpaRepository<AllFile,Long> {
@Query("SELECT a From AllFile a where a.guid = :guid")
AllFile findByGuid(@Param("guid") String guid);
}
package com.example.spingaoprepository.repository;
import com.example.spingaoprepository.model.AllFile;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.stereotype.Repository;
import javax.persistence.Entitymanager;
@Repository
public class AllFileRepositoryImpl extends SimpleJpaRepository<AllFile,Long> implements AllFileRepository {
public AllFileRepositoryImpl(Entitymanager em) {
super(AllFile.class,em);
}
@Override
public AllFile findByGuid(String guid) {
System.out.println("Finding AllFile by GUID " + guid);
return null;
}
}
package com.example.spingaoprepository.serializable;
import com.example.spingaoprepository.repository.AllFileRepository;
import com.example.spingaoprepository.service.Pipelineservice;
import com.example.spingaoprepository.utils.ApplicationContextUtils;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
public class PipelineConfigurer {
private ApplicationContext applicationContext = ApplicationContextUtils.getApplicationContext();
private Pipelineservice pipelineservice = applicationContext.getBean(Pipelineservice.class);
public void initialize() {
AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
autowireCapableBeanFactory.autowireBean(pipelineservicE);
AllFileRepository allFileRepository = (AllFileRepository) AopProxyUtils
.getSingletonTarget(pipelineservice.getAllFileRepository());
allFileRepository.findByGuid("XY-123");
}
}
,
使用@Autowired 您正在注入一个实现 AllFileRepository 的对象。这个单例是在启动时创建的,因此你可以使用 is with allFileRepository.findByGuid("");
以上是大佬教程为你收集整理的如何使用代理解析从 SimpleJpaRepository<T,ID> 对象取回存储库接口对象全部内容,希望文章能够帮你解决如何使用代理解析从 SimpleJpaRepository<T,ID> 对象取回存储库接口对象所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。