美文网首页
mybatis源码学习-自动配置原理

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

作者: 一驴绝尘 | 来源:发表于2018-08-14 11:57 被阅读0次

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

    这个地方涉及到 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);

        }

    }

    相关文章

      网友评论

          本文标题:mybatis源码学习-自动配置原理

          本文链接:https://www.haomeiwen.com/subject/vbymbftx.html