gpt4 book ai didi

java - Spring Data 存储库是如何实际实现的?

转载 作者:IT老高 更新时间:2023-10-28 11:38:36 28 4
gpt4 key购买 nike

我在我的项目中使用 Spring Data JPA 存储库已经有一段时间了,我知道以下几点:

  • 在存储库接口(interface)中,我们可以添加 findByCustomerNameAndPhone() 等方法(假设 customerNamephone 是域对象中的字段) .
  • 然后,Spring 通过在运行时(应用程序运行期间)实现上述存储库接口(interface)方法来提供实现。

我对它的编码方式很感兴趣,并且查看了 Spring JPA 源代码和 API,但我找不到以下问题的答案:

  1. 如何在运行时生成存储库实现类以及如何实现和注入(inject)方法?
  2. Spring Data JPA 是否使用 CGlib 或任何字节码操作库来实现方法并动态注入(inject)?

您能否帮助解决上述问题并提供任何支持的文档?

最佳答案

首先,没有代码生成,这意味着:没有 CGLib,根本没有字节码生成。基本方法是使用 Spring 的 ProxyFactory API 以编程方式创建 JDK 代理实例来支持接口(interface),并且 MethodInterceptor 拦截对实例的所有调用并将方法路由到适当的地点:

  1. 如果存储库已使用自定义实现部分进行了初始化(请参阅 that part of the reference documentation 了解详细信息),并且调用的方法在该类中实现,则调用将路由到那里。
  2. 如果方法是查询方法(参见 DefaultRepositoryInformation 了解如何确定),存储特定的查询执行机制将启动并执行确定为在启动时为该方法执行的查询。为此,存在一种解析机制,该机制试图识别在不同位置显式声明的查询(在方法上使用 @Query,JPA 命名查询)最终退回到从方法名称派生的查询。查询机制检测见JpaQueryLookupStrategy .查询推导的解析逻辑见PartTree .可以看到商店特定于实际查询的翻译,例如在 JpaQueryCreator .
  3. 如果上述方法均不适用,则执行的方法必须是由特定于商店的存储库基类(在 JPA 的情况下为 SimpleJpaRepository)实现的方法,并且调用被路由到该类的实例中。

实现该路由逻辑的方法拦截器是QueryExecutorMethodInterceptor,高级路由逻辑见here .

这些代理的创建被封装到一个标准的基于 Java 的工厂模式实现中。高级代理创建可以在 RepositoryFactorySupport 中找到.然后,特定于商店的实现会添加必要的基础架构组件,这样对于 JPA,您就可以继续编写如下代码:

EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);

我明确提到这一点的原因是,应该清楚的是,在其核心中,这些代码首先不需要 Spring 容器来运行。它需要 Spring 作为类路径上的库(因为我们不想重新发明轮子),但通常与容器无关。

为了简化与 DI 容器的集成,我们当然构建了与 Spring Java 配置、XML 命名空间以及 CDI extension 的集成。 , 以便 Spring Data 可以在普通 CDI 场景中使用。

关于java - Spring Data 存储库是如何实际实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38509882/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com