1. 自动配置源码分析

使用 Spring Boot 开发较之以前的基于 xml 配置式的开发,要简捷方便快速的多。而这完全得益于 Spring Boot 的自动配置。下面就通过源码阅读方式来分析自动配置的运行原理。

1.1 解析@SpringBootApplication

打开启动类的@SpringBootApplication 注解源码。
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

我们发现@SpringBootApplication 注解其实就是一个组合注解。
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

注解是 JDK5 中的新特性(2004 年),Spring 第一个版本是 2003 年 2 月开始开发,Spring2 中开始出现了量注解。

(1) 元注解

前四个是专门(即只能)用于对注解进行注解的,称为元注解。

  • @Target
  • @Retention
  • @Documented
  • @Inherited:表示该注解会被子类自动继承。

(2) @SpringBootConfiguration

查看该注解的源码注解可知,该注解与@Configuration 注解功能相同,仅表示当前类为一个 JavaConfig 类,其就是为 Spring Boot 专门创建的一个注解。
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

(3) @ComponentScan

顾名思义,用于完成组件扫描。不过需要注意,其仅仅用于配置组件扫描指令,并没有真正扫描(即配置扫哪些包路径、包括哪些类、排除哪些类等等配置信息),更没有装配其中的类,这个真正扫描是由@EnableAutoConfiguration 完成的。
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

(4) @EnableXxx

@EnableXxx 注解一般用于开启某一项功能,是为了简化代码的导入,即使用了该类注解,就会自动导入某些类。所以该类注解是组合注解,一般都会组合一个@Import 注解,用于导入指定的多个类,而被导入的类一般分为三种:配置类、选择器,与注册器

  • A、配置类
    @Import 中指定的类一般以 Configruation 结尾,且该类上会注解@Configuration,表示当前类为一个配置类。
    Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
    Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

  • B、 选择器
    @Import 中指定的类一般以 Selector 结尾,且该类实现了 ImportSelector 接口,表示当前类会根据条件选择要导入的类。
    Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

  • C、 注册器
    @Import 中指定的类一般以 Registrar 结尾,且该类实现了 ImportBeanDefinitionRegistrar接口,用于导入注册器,该类可以在代码运行时动态注册指定类的实例。
    Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

1.2 解析@EnableAutoConfiguration

Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

该注解用于开启自动配置,是 Spring Boot 的核心注解,是一个组合注解。所谓自动配置是指,其会自动找到其所需要的类,然后交给 Spring 容器完成这些类的装配。

(1) @Import

用于导入框架本身所包含的自动配置相关的类。其参数 AutoConfigurationImportSelector类,该类用于导入自动配置的类。
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

我们看下SpringBoot内置的自动配置相关的自动配置类加载的文件:
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

自动配置之所以能完成就是因为有这些自动配置类,怎么完成后面分析。

DEBUG
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

(2) @AutoConfigurationPackage

用于导入用户自定义类,即自动扫描包中的类。
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

DEBUG:
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
关于注册讲SpringCloud的Eureka会详细解析

2. Spring Boot 与 Redis 的整合

Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

在 spring.factories 中有一个 RedisAutoConfiguration 类,通过前面的分析我们知道,该类一定会被 Spring 容器自动装配。但自动装配了就可以读取到 Spring Boot 配置文件中 Redis相关的配置信息了?这个类与 Spring Boot 配置文件是怎么建立的联系?

先打开这个类看一下:
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

虽然这个类配置在了自动配置文件中,但不会立即加载这个类到内存,是有条件的:

  • @ConditionalOnCass(RedisOperations.class):当类路径下有这个类的class文件的时候,当前配置类才会起作用
  • @EnableConfigurationProperties(RedisProperties.class):开启配置属性的功能
    • RedisProperties.class:
      Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

    • @EnableConfigurationProperties

  • @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class }):导入Lettuce和Jedis连接配置

Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

3. MyBatis 与 Spring Boot 的整合

Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

在 External Libraries 中找到 mybatis-spring-boot-starter 依赖。而该依赖又依赖于mybatis-spring-boot-autoconfigurigure。其 META-INF 中有 spring.factories 文件,打开这个文件我们找到了 Mybatis 的自动配置类。
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

我们看MybatisAutoConfiguration这个类:
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

有这么多个条件:

  • @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class }):当前类路径下需要有SqlSessionFactory和SqlSessionFactoryBean的class文件
  • @ConditionalOnBean(DataSource.class):当前容器中需要有DataSource的实例
  • @EnableConfigurationProperties(MybatisProperties.class):封装的是Mybatis配置属性
  • @AutoConfigureAfter(DataSourceAutoConfiguration.class):当前配置类必须在DataSourceAutoConfiguration之后配置

该类中还包含两个@Bean 方法用于创建相应的 Bean。
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)
Spring Boot 源码分析(自动配置、Spring Boot 与 Redis 的整合、MyBatis 与 Spring Boot 的整合)

分类:

技术点:

相关文章: