数据源自动配置
spring.factories中找到数据源的配置类:
Mybatis自动配置源码分析
1、springboot项目最核心的就是自动加载配置,该功能则依赖的是一个注解 @SpringBootApplication中的@EnableAutoConfiguration 
2、EnableAutoConfiguration主要是通过AutoConfigurationImportSelector类来加载
以mybatis为例,*selector(所有的selector)通过反射加载spring.factories中指定的java类,也就是加载 MybatisAutoConfiguration类(该类有Configuration注解,属于配置类)


3、MybatisAutoConfiguration: 
①类中有个MybatisProperties类,该类对应的是mybatis的配置文件 
②类中有个sqlSessionFactory方法,作用是创建SqlSessionFactory类、Configuration类 (mybatis最主要的类,保存着与mybatis相关的东西) 
③SelSessionTemplate,作用是与mapperProoxy代理类有关  
sqlSessionFactory主要是通过创建了一个SqlSessionFactoryBean,这个类实现了FactoryBean接 口,所以在Spring容器就会注入这个类中定义的getObject方法返回的对象。
看一下getObject()方法做了什么?
 这个已经很明显了,实际上就是调用了MyBatis的初始化流程 现在已经得到了SqlSessionFactory了,接下来就是如何扫描到相关的Mapper接口了。 
这个需要看这个注解  
@MapperScan(basePackages = “com.mybatis.mapper”)@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(MapperScannerRegistrar.class)@Repeatable(MapperScans.class)public @interface MapperScan
 
通过@Import的方式会扫描到MapperScannerRegistrar类。 MapperScannerRegistrar实现了ImportBeanDefinitionRegistrar接口,那么在spring实例化之前 就会调用到registerBeanDefinitions方法  
public class MapperScannerRegistrar implementsImportBeanDefinitionRegistrar, ResourceLoaderAware
@Overridepublic void registerBeanDefinitions(AnnotationMetadataimportingClassMetadata, BeanDefinitionRegistry registry) {//拿到MapperScan注解,并解析注解中定义的属性封装成AnnotationAttributes对象AnnotationAttributes mapperScanAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));if (mapperScanAttrs != null) {registerBeanDefinitions(importingClassMetadata, mapperScanAttrs,registry,generateBaseBeanName(importingClassMetadata, 0));}}//........
MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor接口,所以接着又会扫 描并调用到postProcessBeanDefinitionRegistry方法。
修改了mapper的beanClass类型为MapperFactoryBea
上述几步主要是完成通过 @MapperScan(basePackages = “com.mybatis.mapper”)这个定义,扫描指定包下的 mapper接口,然后设置每个mapper接口的beanClass属性为MapperFactoryBean类型并加入 到spring的bean容器中。
MapperFactoryBean实现了FactoryBean接口,所以当spring从待实例化的bean容器中遍历到这 个bean并开始执行实例化时返回的对象实际上是getObject方法中返回的对象。
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implementsFactoryBean<T>
最后看一下MapperFactoryBean的getObject方法,实际上返回的就是mybatis中通过getMapper 拿到的对象,熟悉mybatis源码的就应该清楚,这个就是mybatis通过动态代理生成的mapper接 口实现类’
@Overridepublic T getObject() throws Exception {return getSqlSession().getMapper(this.mapperInterface);}
到此,mapper接口现在也通过动态代理生成了实现类,并且注入到spring的bean容器中了,之后 使用者就可以通过@Autowired或者getBean等方式,从spring容器中获取到了
