程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何使用代理解析从 SimpleJpaRepository<T,ID> 对象取回存储库接口对象大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何使用代理解析从 SimpleJpaRepository<T,ID> 对象取回存储库接口对象?

开发过程中遇到如何使用代理解析从 SimpleJpaRepository<T,ID> 对象取回存储库接口对象的问题如何解决?下面主要结合日常开发的经验,给出你关于如何使用代理解析从 SimpleJpaRepository<T,ID> 对象取回存储库接口对象的解决方法建议,希望对你解决如何使用代理解析从 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,请注明来意。
标签: