mybatis源码学习-自动配置原理

原创不易,转载请写明出处

这个地方涉及到 spring boot 自动配置,就先聊聊spring boot的自动配置原理,在sping boot 的自动配置中,最重要的注解是如下注解,保留核心代码

@Import(EnableAutoConfigurationImportSelector.class)

public @interface EnableAutoConfiguration {

}

看看 EnableAutoConfigurationImportSelector的代码实现,也是保留核心逻辑

public class EnableAutoConfigurationImportSelector implements DeferredImportSelector{

@Override

public String[] selectImports(AnnotationMetadata metadata) {

    List configurations = getCandidateConfigurations(metadata, attributes);

     return configurations.toArray(new String[configurations.size()]);

  }

}

下面贴出getCandidateConfigurations()方法的代码实现,也是保留核心逻辑

protected List getCandidateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes) {

     List configurations = SpringFactoriesLoader.loadFactoryNames(

     getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());

     return configurations;

}

这个地方 getSpringFactoriesLoaderFactoryClass()获取的是 EnableAutoConfiguration.class,也就是上面的自动配置的注解

再来看看SpringFactoriesLoader类中的 loadFactoryNames()方法

public static ListloadFactoryNames(Class factoryClass, ClassLoader classLoader) {

// 这个地方是 org.springframework.boot.autoconfigure.EnableAutoConfiguration

String factoryClassName = factoryClass.getName();

//  FACTORIES_RESOURCE_LOCATION 的内容是"META-INF/spring.factories"

Enumeration urls = (classLoader !=null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :

ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));

      List result =new ArrayList();

      while (urls.hasMoreElements()) {

      URL url = urls.nextElement();

        Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));

        String factoryClassNames = properties.getProperty(factoryClassName);

        result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));

      }

return result;

}

以上代码做的事情就是获取类加载器classLoader下,所有的资源名为META-INF/spring.factories的资源,之后读取文件转化为properties 文件获取key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的value,之后把逗号分隔的字符串转化为数组,返回,返回的数组内容就是要初始化的配置类的名字,下面截取了spring-boot-autoconfigure包中的文件spring.factories 返回的数组

org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,

org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,

org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,

org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

最后一个是比较重要的配置,数据源的自动配置,有兴趣可以自己看一下,上面说了spring-boot的自动配置原理,下面看看mybatis-spirng-boot-autoconfigure的自动配置原理,这个包主要依赖了 mybatis, 以及 mybatis-spring,它的 META-INF/spring.factories中的内容为 

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

也就是说,在spring-boot添加@EnableAutoConfiguration注解时,会去自动实例化 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration类

MybatisAutoConfiguration类中,主要核心逻辑如下

// 很重要的方法,读取yml初始化SqlSessionFactory, 采用的是默认实现类 DefaultSqlSessionFactory,

// 在SqlSessionFactoryBuilder 中的 build(Configuration)

@Bean

@ConditionalOnMissingBean

public SqlSessionFactorysqlSessionFactory(DataSource dataSource)throws Exception {

// 项目启动的时候初始化 SqlSessionFactoryBean,设置成员变量,这个成员变量是从yml等配置文件读来的,也就是spring boot

    SqlSessionFactoryBean factory =new SqlSessionFactoryBean();

    factory.setDataSource(dataSource);

    factory.setVfs(SpringBootVFS.class);

    //设置springBoot解析的配置,可以设置configLocation,也可以设置configuration,只能设置其一

    if (StringUtils.hasText(this.properties.getConfigLocation())) {

factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));

    }

factory.setConfiguration(properties.getConfiguration());

    if (this.properties.getConfigurationProperties() !=null) {

factory.setConfigurationProperties(this.properties.getConfigurationProperties());

    }

if (!ObjectUtils.isEmpty(this.interceptors)) {

factory.setPlugins(this.interceptors);

    }

if (this.databaseIdProvider !=null) {

factory.setDatabaseIdProvider(this.databaseIdProvider);

    }

if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {

factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());

    }

if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {

factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());

    }

if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {

factory.setMapperLocations(this.properties.resolveMapperLocations());

    }

// springBoot配置完成后解析config.xml

    return factory.getObject();

}

// 初始化 sqlSessionTemplate,自动注入sqlSessionFactory

@Bean

@ConditionalOnMissingBean

public SqlSessionTemplatesqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {

ExecutorType executorType =this.properties.getExecutorType();

    if (executorType !=null) {

return new SqlSessionTemplate(sqlSessionFactory, executorType);

    }else {

return new SqlSessionTemplate(sqlSessionFactory);

    }

}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,337评论 19 139
  • SpringMVC原理分析 Spring Boot学习 5、Hello World探究 1、POM文件 1、父项目...
    jack_jerry阅读 1,465评论 0 1
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,229评论 6 342
  • 第5章 Spring Boot自动配置原理 5.1 SpringBoot的核心组件模块 首先,我们来简单统计一下S...
    光剑书架上的书阅读 49,113评论 5 65
  • 我一直具有留意微小事物的特长。这是非自诩的事实。任何人。任何经不经意的小动作。只要我注意,就记住下去。渐渐的,这些...
    周摧花阅读 866评论 0 0

友情链接更多精彩内容