Analysis of the principle of spring data jpa

       When we inject a standard spring data jpa repository into other spring beans, we will find that the repository is actually

JdkDynamicAopProxy生成的一个代理类(org.springframework.data.jpa.repository.support.SimpleJpaRepository@5748638c)。查看SimpleJpaRepository源码会发现SimpleJpaRepository中有CrudRepository接口所有方法的实现。当我们调用CrudRepository中的方法时,实际上是调用SimpleJpaRepository中对应的方法。而我们在repository中自定义方法则是通过在生成代理类的同时,添加的MethodInterceptor实现。

Source code analysis:

Taking @Resource injection bean as an example, the final realization of injection is org.springframework.context.annotation.CommonAnnotationBeanPostProcessor. When the spring container is started, it will obtain the corresponding bean injection from the bean container. Singleton bean acquisition will call org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法,具体获取bean的代码是
singletonObject = singletonFactory.getObject(),可以看出是通过该方法第二个参数中的方法获取的,而ObjectFactory是一个接口,

There is only one method in this interface

T getObject() throws BeansException, found through the call stack, calling the getSingleton method is the doGetBean method in org.springframework.beans.factory.support.AbstractBeanFactory, the specific code is as follows:

if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try {
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         // Explicitly remove instance from singleton cache: It might have been put there
         // eagerly by the creation process, to allow for circular reference resolution.
         // Also remove any beans that received a temporary reference to the bean.
         destroySingleton(beanName);
         throw ex;
      }
   });
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

It is found that the incoming ObjectFactory is a lambda expression, which is how spring creates a singleton bean call. Spring will initialize the bean after instantiating the bean object. During initialization, if the bean implements the InitializingBean interface, it will call the afterPropertiesSet() method of InitializingBean. The bean created by the repository in this step implements the interface https://blog.csdn.net/sinat_33472737/article/details/105838278 . Eventually, the afterPropertiesSet method in org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport will be called. The distribution will initialize some member variables, what we care about is

this.repository = Lazy.of(() -> this.factory.getRepository(repositoryInterface, repositoryFragmentsToUse));接着往下看,factory.getRepository调用的是org.springframework.data.repository.core.support.RepositoryFactorySupport中的getRepository方法。
result.addAdvice(new QueryExecutorMethodInterceptor(information, projectionFactory));该行代码就是给我们在repository中自定义的根据方法名生成对应sql的通知拦截器
T repository = (T) result.getProxy(classLoader);该行代码就是生成代理repository的。调试发现该方法最终返回的就是SimpleJpaRepository代理类

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/sinat_33472737/article/details/104904535