1. 实例化对象中有一种是实现factoryBean接口,为什么不用无参/有参构造直接造对象?当对象构造过程十分复杂的时候才会实现factoryBean接口

    image-20210513184727966.png

    sqlSessionFactoryBean就实现了factoryBean接口,我们需要sqlSessionFa toryBean返回sqlSessionFactory对象,这个返回的过程在重写getObject的方法
    
    //config.xml文件,也是需要解析的文件
    <configuration>
     <!-- 全局的setting配置 根据需要添加  需要二级缓存 延迟加载 就可以配置-->
    
    
     <!-- 配置别名 -->
       <typeAliases>
          <!-- 批量扫描别名 -->
           <package name="com.fuchanghai.mybatis.pojo"/>
            <!--<package name="cn.zx.ssm.po"/>  -->
       </typeAliases>
    <!-- 使用自动扫描器时,mapper.xml文件如果和mapper.java接口在一个目录则此处不用定义mappers 
       -->
     <mappers>
          <package name="com.fuchanghai.mybatis.mapper" />
       </mappers>  
    </configuration>
    
     public SqlSessionFactory getObject() throws Exception {
            if (this.sqlSessionFactory == null) {
                this.afterPropertiesSet();//找不到sqlSessionFactory就进入这个方法
            }
    
            return this.sqlSessionFactory;//有的化直接返回
        }
    
     public void afterPropertiesSet() throws Exception {
            Assert.notNull(this.dataSource, "Property 'dataSource' is required");
            Assert.notNull(this.sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
            Assert.state(this.configuration == null && this.configLocation == null || this.configuration == null || this.configLocation == null, "Property 'configuration' and 'configLocation' can not specified with together");
            this.sqlSessionFactory = this.buildSqlSessionFactory();//这里调用这个方法返回sqlSessionFactory对象
        }
    
    protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
            XMLConfigBuilder xmlConfigBuilder = null;//用来解析数据
            Configuration configuration;//把解析的数据存放到这个对象中
            //...此时已经拿到到xmlConfigBuilder
             if (xmlConfigBuilder != null) {
                try {
                    xmlConfigBuilder.parse();
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("Parsed configuration file: '" + this.configLocation + "'");
                    }
                } catch (Exception var22) {
                    throw new NestedIOException("Failed to parse config resource: " + this.configLocation, var22);
                } finally {
                    ErrorContext.instance().reset();
                }
            }
    }
    
     public Configuration parse() {
            if (this.parsed) {
                throw new BuilderException("Each XMLConfigBuilder can only be used once.");
            } else {
                this.parsed = true;
                this.parseConfiguration(this.parser.evalNode("/configuration"));//这里正式解析config.xml配置文件
                return this.configuration;
            }
        }
    

    随便一个获取xml名字的点进去
    image-20210513191104473.png
    image-20210513191249391.png

    最终都把解析的内容赋值到了configration中

    //注意parse中的 
    this.mapperElement(root.evalNode("mappers"));
    //点进去,去找package属性,找到直接加入到configration中,找不到就找resource、url、class(不能共存,只能存在一个),最终处理后的数据也添加到configration中
    

    image-20210513191606885.png

    //到这里configation已经装配完毕,然后交给sqlSessionFactoryBuilder解析,返回的就是sqlSessionFactory
    return this.sqlSessionFactoryBuilder.build(configuration);
    

    这里注册的sqlSessionFactory会存储在BeanDefinitionRegistry中