我在项目中使用Spring Data JPA仓库已有一段时间了,我知道以下几点:
findByCustomerNameAndPhone()
customerName
phone
然后,Spring通过在运行时(在应用程序运行期间)实现上述存储库接口方法来提供实现。 我对它的编码方式很感兴趣,并查看了Spring JPA源代码和API,但是找不到以下问题的答案:
如何在运行时生成存储库实现类以及如何实现和注入方法?
首先,没有代码生成正在进行,这意味着:没有CGLib,根本没有字节代码生成。基本方法是使用Spring的ProxyFactoryAPI以编程方式创建JDK代理实例以支持该接口,并MethodInterceptor拦截所有对该实例的调用并将该方法路由到适当的位置:
ProxyFactoryAPI
MethodInterceptor
JpaQueryLookupStrategy
JpaQueryCreator
QueryExecutorMethodInterceptor
这些代理的创建被封装到基于Java的标准Factory模式实现中。可以在中找到高级代理创建RepositoryFactorySupport。然后,特定于商店的实现将添加必要的基础结构组件,以便对于JPA而言,您可以继续编写以下代码:
RepositoryFactorySupport
EntityManager em = … // obtain an EntityManager JpaRepositoryFactory factory = new JpaRepositoryFactory(em); UserRepository repository = factory.getRepository(UserRepository.class);
我明确提到的原因是,应该清楚的是,从根本上讲,该代码中的任何内容都不需要Spring容器来运行。它需要Spring作为类路径上的库(因为我们不想重塑轮子),但是通常与容器无关。
为了简化与DI容器的集成,我们当然要与Spring Java配置,XML名称空间以及CDI扩展进行集成,以便可以在普通CDI场景中使用Spring Data。