什么是 SpringBoot:
简化 Spring 应用的初始搭建以及开发的过程,作用能帮我们快速的构建 Spring 项目,解决了添加添加 Maven 依赖关系、配置应用程序服务器,并减少了 Spring的 xml 配置,做到开箱即用。
SpringBoot 三大注解:
Springboot 核心注解:@SpringBootApplication 注解内部是三大注解功能的集成:
- @ComponentScan:开启组件扫描;
- @SpringBootConfiguration:作用等于 @Configuration 注解,用于标记这个类是配置类;
- @EnableAutoConfiguration:自动装配的(自动配置的主要是这个注解)
1、@ComponentScan(“指定包路径”):
此注解表示开启组件扫描器,默认扫描当前注解所在的配置类所在的包的所有注解组件加载到 Spring容器中(@Service/@Controller/@Component 等),替代 xml 配置中的context:component-scan/ 标签。自动扫描并加载符合条件的组件或者 bean,将这个bean 定义加载到 IoC 容器中。
2、@SpringBootConfiguration:
SpringBoot 的配置类,表示这个是 SpringBoot 的配置类;这个注解的底层是一个 @Configuration 注解,把类声明为配置类,是一个 IoC 容器,支持 JavaConfig 的方式来进行配置;
里面还有其他注解:
// 点进去得到下面的 @Component
@Configuration
public @interface SpringBootConfiguration {}
@Component
public @interface Configuration {}
@Configuration:说明这是一个配置类;
@Component:启动类本身也是 Spring 的一个组件而已,负责启动应用
3、@EnableAutoConfiguration:
这个注解表明启动自动装配,里面包含了两个比较重要的注解:@AutoConfigurationPackage 和 @Import(AutoConfigurationImportSelector.class)
- @AutoConfigurationPackage 和 @ComponentScan 注解一样,也是将主配置类所在包及其子包里面的组件扫描到 IoC 容器中,但是区别于:
@AutoConfigurationPackage 扫描 @Entity、@MapperScan 等第三方依赖的注解;
@ComponentScan 扫描 @Controller、@Service、@Component、@Respository 这些常见注解。 所以这两个注解扫描的对象是不一样的。
- @Import(AutoConfigurationImportSelector.class) 是自动装配的核心:
AutoConfigurationImportSelector的类,这个类它有一个selectorImport的方法,这个方法又调用了一个getCandidateConfigurations方法,这个方法内部通过SpringFactoriesLoader.loadFactoryNames最终调用loadSpringFactories加载到一个META-INF下的spring.factories文件。打开这个文件可以看到是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表,这些类名以逗号分隔。
其中 Spring.factories 文件是一组组的 key=value 形式,key 为 EnableAutoConfiguration 的全类名,value 为 一个 XxxAutoConfiguration 自动配置类名的列表,以逗号分隔。
最终,@EnableAutoConfiguration 注解通过 @SpringBootApplication 注解被间接的标记在 SpringBoot 的启动类上,SringApplication.run 方法的内部就会执行了 selectImports(选择导入) 方法,进而找到 JavaConfig 配置类全限定名对应的 class ,然后将所有自动配置类加载到 IoC 容器中。
自动配置类开启了 @EnableConfigurationProperties(XxxProperties.class)注解 (启动配置属性(导入对应的属性类)),最终找到对应的配置属性类(XxxProperties)。在全局配置的属性(如:servlet.port 等),通过 @ConfigurationProperties( perfix = “前缀”) 注解(配置属性),将全局配置文件中按照前缀配置的属性值绑定到对应的 XxxProperties 配置实体类上封装为一个 bean,然后通过 @EnableConfigurationProperties 注解将属性类 XxxProperties 对象 (bean) 导入到自动配置类 (XxxAutoConfiguration) 容器中。
如果需要修改自动配置对象中的配置,每一个自动配置对象都会有对应的XxxProperties,这个类上贴有@ConfigurationProperties(prefix=“前缀”),开发者可以通过全局配置文件去给其添加配置。在配置文件中写出前缀,然后再给需要配置的属性配置,XxxProperties就会去读取得在全局配置文件中配置的属性,赋值给类中的属性。然后在XxxAutoConfiguration中引入对应的XxxProperties对象,这样XxxAutoConfiguration 这个配置类中就会有配置好的XxxProperties对象。在XxxAutoConfiguration配置类中创建对象时,比如创建连接池这些的时候,就能拥有开发设置进来的配置,然后再注入对象的属性中,达到配置成功,帮我们创建对象。
如果不需要开发者添加配置的,Spring Boot会自动帮我们加载自动配置对象,里面的值将会是默认值。例如:ServletWebServiceFactorAutoConfiguration 为例,它是 Servlet 容器的自动配置类,该类开启了 @EnableConfigurationProperties(ServletProperties.class) 注解,最终找到了 ServletProperties 类,在全局配置的属性,如:servlet.port 等,@ConfigurationProperties( perfix = “servlet.port”) 注解,将配置的属性值绑定到ServletProperties 配置实体类上封装为一个 Bean。然后通过 @EnableConfigurationProperties 注解在 ServletWebServiceFactorAutoConfiguration 配置类中导入 ServletProperties 对象,这样自动配置类就会有在全局配置文件中配置的值。
总结:
SpringBoot 启动的时候通过 @EnableAutoConfiguration 注解找到 META-INF/spring.factories 文件中的所有自动配置类,并对其加载,这些自动配置类都是以 XxxAutoConfiguration 命名。它实际就是一个 JavaConfig 形式的 IoC 容器配置类,通过 XxxProperties 类中取得在全局配置文件中配置的属性,如:Servlet.port 。
*AutoConfiguration 类:自动配置类,添加到 IoC 容器中。
*properties 类:封装配置文件相关属性。
开启自动配置功能:
自动配置注解的原理:内部导入了 AutoConfigurationImportSelect,这个类中有个 getCandiateConfiguration 方法(获取候选的配置),读取 jar 包中的 META-INF/spring.factories 文件中的配置类(XxxAutoConfiguration),再根据条件进行加注和配置(一般配置类中有个对应的 Xxxproperties 类,这个类贴了 @ConfigurationProperties(prefix = “前缀”)),有个前缀,读取在 application的配置文件中对应前缀配置的信息,我们编写的配置文件 application/yml 就是要根据这些前缀编写。
- SpringBoot 在启动的时候从类路径下的 META-INF/spring.factories 中获取 EnableAutoConfiguration 指定的值。
- 将这些值作为自动配置类导入容器,自动配置类就生效,帮我们进行自动配置功能;
- 整个 J2EE 的整体解决方案和自动配置 都在 SpringBoot-AutoConfiguration 的 jar 包中;
- 它会给容器中导入非常多的自动配置类(XxxAutoConfiguration ),就是给容器中导入整个场景需要的所有组件,并配置好这些组件;
- 有了自动配置类,就免去了我们手动编写配置注入功能组件等功能。