zoukankan      html  css  js  c++  java
  • 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是怎么注入的了

  • 相关阅读:
    自然语言处理(三)——PTB数据的batching方法
    自然语言处理(二)——PTB数据集的预处理
    自然语言处理(一)——语言模型评价方法
    TensorFlow数据集(二)——数据集的高层操作
    TensorFlow数据集(一)——数据集的基本使用方法
    TensorFlow多线程输入数据处理框架(四)——输入数据处理框架
    Node的简介
    seajs的原理以及基本使用
    git常用指令
    一个小白的四次前端面试经历
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14004855.html
Copyright © 2011-2022 走看看