深入源码理解Spring整合MyBatis原理 (2)

可以看到BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,那么该接口的实现类一定会在Spring应用上下文生命周期中回调相关接口方法。

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { /** * Modify the application context's internal bean definition registry after its * standard initialization. All regular bean definitions will have been loaded, * but no beans will have been instantiated yet. This allows for adding further * bean definitions before the next post-processing phase kicks in. * @param registry the bean definition registry used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; } BeanFactoryPostProcessor接口

这个接口是干什么的?它有自己的抽象方法,在Spring应用上下文生命周期的"invokeBeanFactoryPostProcessors"环节会回调相关方法。(这里不是重点不过多聊)

我们这次关注的重点是它的子接口-BeanDefinitionRegistryPostProcessor,Spring在上述环节中对该接口做了特殊处理,回调了它的独有方法。(如上面的代码段所示)

BeanDefinitionRegistryPostProcessor接口回调

AbstractApplicationContext#refresh()方法即为Spring应用上下文的生命周期的刷新入口,可以看到在比较前置的环节就会先处理BeanFactoryProcessor类型的Bean。

深入源码理解Spring整合MyBatis原理

追进源码后发现最后会在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()方法中循环处理所有BeanFactoryProcessor,其中如果是BeanDefinitionRegistryPostProcessor则会回调BeanDefinitionRegistryPostProcessor的独有方法,值得注意的是该方法的入参是一个BeanDefinitionRegistry

(关于BeanDefinitionRegistry有必要在单独段落做介绍,所以请先移步下一段落吧)

深入源码理解Spring整合MyBatis原理

在了解了这几个接口后,我们汇总一下就明白了BeanDefinitionRegistryPostProcessor的能力了。它可以在Spring应用上下文前期先被实例化且回调相关接口方法,向Spring容器注册或移除BeanDefinition甚至可以在get出一个BeanDefinition后直接修改内部属性,让Bean变成你想要的模样。

BeanDefinitionRegistry接口 BeanDefinition是什么?

BeanDefinition是Spring实例化一个Bean的依据,它的内部维护了一个Bean的各种属性,如BeanClass、BeanName、lazyInit(是否懒加载)、primary、scope等等。

而Spring在实例化一个Bean的时候需要先从一个Map中根据beanName获取到对应的BeanDefinition才能去按需实例化SpringBean,如下。

DefaultListableBeanFactory#getBeanDefinition()

深入源码理解Spring整合MyBatis原理

看看这个Map的定义

BeanDefinition

相信大家也猜到了,上面提到的就是维护这个Map的。
BeanDefinitionRegistry接口的方法如下:

深入源码理解Spring整合MyBatis原理


可以看到该接口的能力就是维护Spring容器中的BeanDefinition。

Spring整合MyBatis正片

有了上面的回顾后,关于Spring整合MyBatis的秘密就很容易揭晓了。

在跟进源码前,我们先思考下如果是你,你会怎么将MyBatis整合进来?达到效果:通过@Autowired将Mapper注入进来便可以直接使用。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzsjsw.html