• Mybatis整合Spring之MapperFactoryBean怎么拿到的SqlSessionFactory


      Mybatis整合Spring源码之前也分析过一次了,这次刚好脑袋灵光一闪,想出来一个在

         SqlSessionDaoSupport.setSqlSessionFactory  是什么时候调用的呢?

    一  BeanDefinition

      每一个mapper接口都会被扫描成一个BeanDefinition,这个BD开始会被强制转成MapperFactoryBean类型,并

      ClassPathMapperScanner.processBeanDefinitions

    private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
        GenericBeanDefinition definition;
        for (BeanDefinitionHolder holder : beanDefinitions) {
          definition = (GenericBeanDefinition) holder.getBeanDefinition();
    
          if (logger.isDebugEnabled()) {
            logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() 
              + "' and '" + definition.getBeanClassName() + "' mapperInterface");
          }
    
          // the mapper interface is the original class of the bean
          // but, the actual class of the bean is MapperFactoryBean
          definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName()); // issue #59
          definition.setBeanClass(this.mapperFactoryBean.getClass());
    
          definition.getPropertyValues().add("addToConfig", this.addToConfig);
    
          boolean explicitFactoryUsed = false;
          if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
            definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
            explicitFactoryUsed = true;

    在这个BD中,mapper的原始类加入到构造方法入参,sqlSessioinFactory放进了bd的属性里

    二 生效时机

      通过构造方法, Class<T> mapperInterface 被注入了

    public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
    
      private Class<T> mapperInterface;
    
      private boolean addToConfig = true;
    
      public MapperFactoryBean() {
        //intentionally empty 
      }
      
      public MapperFactoryBean(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
      }

    sqlSessioinFactory的注入在对bean的初始化的第二步

      

    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
            PropertyValues pvs = mbd.getPropertyValues();
    
            if (hasInstAwareBpps || needsDepCheck) {//这部分是对@AutoWired或者@Resource进行注入的
                PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                if (hasInstAwareBpps) {
                    for (BeanPostProcessor bp : getBeanPostProcessors()) {
                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                            pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                            if (pvs == null) {
                                return;
                            }
                        }
                    }
                }
                if (needsDepCheck) {
                    checkDependencies(beanName, mbd, filteredPds, pvs);
                }
            }
         //走完了上面的代码后这个bean的@AutoWired或者@Resource的属性就已经注入完了
         applyPropertyValues(beanName, mbd, bw, pvs); //这个方法处理的是BeanDefinition里的静态属性,也就是BeanDefinition里已经写好了的属性
    }

     applyPropertyValues 会对BD中的全部属性进行处理,我看了下调用还有点复杂,不过底层应该还是通过Field的反射接口

    这样,我们就知道了sqlSessioinFactory是怎么注入的了

  • 相关阅读:
    unity3d 打包个人记录
    Unity3d 协程
    Unity3d 复制文字到剪切板及存储图像到相册
    为什么 redo log 具有 crash-safe 的能力,是 binlog 无法替代的?
    Java源码系列4——HashMap扩容时究竟对链表和红黑树做了什么?
    深入理解Java虚拟机1——内存区域
    Java源码系列3——LinkedHashMap
    深入理解Java虚拟机2——对象探秘
    高效学习
    WordPress自动代码高亮
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14004855.html
Copyright © 2020-2023  润新知