spring boot原理分析
1、分析spring-boot-starter-parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
他的父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
他来真正管理Spring Boot应用里面的所有依赖版本;
按照Ctrl点击pom.xml中的spring-boot-starter-dependencies,跳转到了spring-boot-starter-dependencies的pom.xml,xml配置如下(只摘抄了部分重点配置):
从上面的spring-boot-starter-dependencies的pom.xml中可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递。以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)
2、分析spring-boot-starter-web启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web:
        spring-boot-starter:spring-boot场景启动器;帮我们导入了web模块正常运行所依赖的组件;
        Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter
       相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器
3、主程序类,主入口类
/**
* @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
*/
@SpringBootApplication
public class HellStartMain {
public static void main(String[] args) {
//spring启动起来
SpringApplication.run(HellStartMain.class);
}
}
1、@SpringBootApplication
Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot
就应该运行这个类的main方法来启动SpringBoot应用;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication
2、@SpringBootConfiguration
SpringBoot的配置类,标注这个类,表明SpringBoot是一个配置类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration{
@Configuration:配置类上面标注这个注解
配置类---配置文件;配置也是一个组件;@Component
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
3、@EnableAutoConfiguration
开启自动配置功能;以前需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效;
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
AutoConfigurationPackage:自动导入包
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage { Spring的底层注解@Import,给容器中导入一个组件;导入的组件由AutoConfigurationPackages.Registrar.class;
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
@Import(AutoConfigurationImportSelector.class)给容器导入组件
public class AutoConfigurationImportSelector{
   public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    } else {
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
        AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
        List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
        configurations = this.removeDuplicates(configurations);
        Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
        this.checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = this.filter(configurations, autoConfigurationMetadata);
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        return StringUtils.toStringArray(configurations);
    }
}
}
EnableAutoConfigurationImportSelector:导入哪些组件的选择器;
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;
会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,
并配置好这些组件;有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;
 SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);
Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,
自动配置类就生效,帮我们进行自动配置工作;以前我们需要自己配置的东西,自动配置类都帮我们;
其中,SpringFactoriesLoader.loadFactoryNames 方法的作用就是扫描所有jar包类路径下 META-INF/spring.factories文件中读取指定类对应的类名称列表,把扫描到的这些文件的内容包装成properties对象
从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

spring.factories 文件中有关自动配置的配置信息如下:

J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-2.0.6.RELEASE.jar;
spring boot原理分析的更多相关文章
- spring boot原理分析启动依赖中parent帮我们干了什么
		主要内容: 1:分析spring-boot-starter-parent 这个依赖 通过前面几篇文章的学习,我们感受到了spring boot的魅力.最明显的感觉就是pom.xml文件.代码少了很多. ... 
- Spring事务原理分析-部分二
		Spring事务原理分析-部分二 说明:这是我在蚂蚁课堂学习了余老师Spring手写框架的课程的一些笔记,部分代码代码会用到余老师的课件代码.这不是广告,是我听了之后觉得很好. 课堂链接:Spring ... 
- Spring事务原理分析-部分一
		Spring事务原理分析-部分一 什么事务 事务:逻辑上的一组操作,组成这组操作的各个单元,要么全都成功,要么全都失败. 事务基本特性 ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要 ... 
- Spring lazy-init 原理分析
		普通的bean的初始化是在容器启动初始化阶段执行的,而被lazy-init修饰的bean 则是在从容器里第一次进行context.getBean(“”)时进行触发.Spring 启动的时候会把所有be ... 
- Spring Mvc原理分析(一)
		Servlet生命周期了解 Servlet的生命(周期)是由容器(eg:Tomcat)管理的,换句话说,Servlet程序员不能用代码控制其生命. 加载和实例化:时机取决于web.xml的定义,如果有 ... 
- Spring事务原理分析--手写Spring事务
		一.基本概念和原理 1.Spring事务 基于AOP环绕通知和异常通知的 2.Spring事务分为编程式事务.声明事务.编程事务包括注解方式和扫包方式(xml) Spring事务底层使用编程事务(自己 ... 
- spring boot 原理解析一(spring boot 基础特征)
		spring boot 提供了完整的介绍 文档:https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/html/documen ... 
- Spring Boot原理
		Spring 钩子之BeanFactoryPostProcessor和BeanPostProcessor的源码学习 https://www.jianshu.com/p/a90a3e617ba6 spr ... 
- Spring核心原理分析之MVC九大组件(1)
		本文节选自<Spring 5核心原理> 1 什么是Spring MVC Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 S ... 
随机推荐
- PHP做ERP, CRM, CMS系统需要注意哪些地方
			php作为二次开发弱类型语言, 可读性, 可视度都是比较高的. 在很多人眼里, 也许php只能做一些web应用开发, 比如某个公司的网站, 某个公司的网站后台, 其实,我可以告诉大家, php不比任何 ... 
- NoSQL 数据库之MongoDB
			1.MongoDB简介 1.1什么是MongoDB MongoDB 是一个跨平台的,面向文档的数据库,是当前 NoSQL 数据库产品中最热门的一种.它介于关系数据库和非关系数据库之间,是非关系数据库当 ... 
- python爬虫基础16-cookie在爬虫中的应用
			Cookie的Python爬虫应用 Cookie是什么 Cookie,有时也用其复数形式 Cookies,英文是饼干的意思.指某些网站为了辨别用户身份.进行 session 跟踪而储存在用户本地终端上 ... 
- ProC第一弹
			编译pro*c 的makefile例子 原来只需在makefile中追加include $(ORACLE_HOME)/precomp/lib/env_precomp.mk,其他一切按照makefile ... 
- LeetCode(200) Number of Islands
			题目 Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is su ... 
- POJ:1753-Flip Game(二进制+bfs)
			题目链接:http://poj.org/problem?id=1753 Flip Game Time Limit: 1000MS Memory Limit: 65536K Description Fl ... 
- JavaSE——Java对象导论
			一.抽象过程 人们所能够解决问题的复杂性直接取决于抽象的类型和质量.所谓抽象的类型指的是抽象的是什么,汇编语言是对底层机器的轻微抽象,命令式语言(FORTRAN.BASIC.C)是对汇编语言的抽象.这 ... 
- CSS效果常见问题
			详细解答参见上篇博客 问题1.如何用 div 画一个 xxx box-shadow 无限投影 (堆叠成复杂图案) ::before ::after 问题2.如何产生不占空间的边框 1.box-shad ... 
- JAVA 基础--开发环境 vscode  搭建
			对于使用 Visual Studio Code 的 Java 开发者来说,Language Support for Java(TM) by Red Hat 扩展提供了非常好的语言特性支持,比如智能感知 ... 
- Linux的档案权限与目录配置练习题
			1.请说明/bin与/usr/bin目录所防止的执行文件有何不同之处:/bin主要放置在开机时,以及进入单人维护模式后还能够被使用的指令,至于/usr/bin则是大部分软件提供的指令放置处 2.请说明 ... 
