SpringBoot 源码解析 (一)----- SpringBoot核心原理入门

目录

Spring Boot 概述什么是 Spring Boot使用 Spring Boot 有什么好处

Spring Boot HelloWorld导入依赖spring boot相关的依赖编写主程序编写Controller、Service运行主程序测试

Hello World探究POM文件启动器主程序类(主入口类)

正文

回到顶部

Spring Boot 概述

Build Anything with Spring Boot:Spring Boot is the starting point for building all Spring-based applications. Spring Boot is designed to get you up and running as quickly as possible, with minimal upfront configuration of Spring.

上面是引自官网的一段话,大概是说: Spring Boot 是所有基于 Spring 开发的项目的起点。Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件。

什么是 Spring Boot

它使用 “习惯优于配置” (项目中存在大量的配置,此外还内置一个习惯性的配置,让你无须手动配置)的理念让你的项目快速运行起来。

它并不是什么新的框架,而是默认配置了很多框架的使用方式,就像 Maven 整合了所有的 jar 包一样,Spring Boot 整合了所有框架

使用 Spring Boot 有什么好处

回顾我们之前的 SSM 项目,搭建过程还是比较繁琐的,需要:

1)配置 web.xml,加载 spring 和 spring mvc

2)配置数据库连接、配置日志文件

3)配置家在配置文件的读取,开启注解

4)配置mapper文件

.....

而使用 Spring Boot 来开发项目则只需要非常少的几个配置就可以搭建起来一个 Web 项目,并且利用 IDEA 可以自动生成生成

划重点:简单、快速、方便地搭建项目;对主流开发框架的无配置集成;极大提高了开发、部署效率。

回到顶部

Spring Boot HelloWorld

导入依赖spring boot相关的依赖

<?xml version="1.0"encoding="UTF-8"?>4.0.0cn.chenhaospringboot1.0.0-SNAPSHOTjarspringbootDemo project for Spring Bootorg.springframework.bootspring-boot-starter-parent2.0.1.RELEASEorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-maven-plugin

编写主程序

/** *@SpringBootApplication来标注一个主程序类,说明这是一个SpringBoot应用 */@SpringBootApplicationpublicclassHelloWorldMainApplication{publicstaticvoidmain(String[] args) {//Spring应用启动SpringApplication.run(HelloWorldMainApplication.class, args); }}

编写Controller、Service

@RestControllerpublicclassHelloController{@RequestMapping("/hello")publicString hello(){return"Hello world"; }}

运行主程序测试

使用maven打包命令将其打包成jar包后,直接使用命令:

java -jar xxx.jar

回到顶部

Hello World探究

POM文件

父项目

org.springframework.bootspring-boot-starter-parent2.0.1.RELEASE

其父项目是

org.springframework.bootspring-boot-dependencies2.0.1.RELEASE../../spring-boot-dependencies

该父项目是真正管理Spring Boot应用里面的所有依赖的版本:Spring Boot的版本仲裁中心,所以以后导入的依赖默认是不需要版本号。如下

还有很多版本号没有截图出来

启动器

org.springframework.bootspring-boot-starter-web

​ spring-boot-starter : spring boot场景启动器;帮助导入web模块正常运行所依赖的组件;

​ Spring Boot将所有的功能场景抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter,那么相关的场景的所有依赖都会导入进项目中。要用什么功能就导入什么场景的启动器。

org.springframework.bootspring-boot-starter-tomcatorg.springframeworkspring-weborg.springframeworkspring-webmvc

添加了 spring-boot-starter-web 依赖,会自动添加 Tomcat 和 Spring MVC 的依赖

spring-boot-starter-web中又引入了spring-boot-starter-tomcat

主程序类(主入口类)

@SpringBootApplicationpublicclassHelloWorldMainApplication{publicstaticvoidmain(String[] args) {//Spring应用启动SpringApplication.run(HelloWorldMainApplication.class, args); }}

@SpringBootApplication

Spring Boot应用标注在某个类上,说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用。

注解定义如下:

@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public@interfaceSpringBootApplication {}

@SpringBootConfiguration

Spring Boot的配置类

标注在某个类上,表示这是一个Spring Boot的配置类

注解定义如下:

@Configurationpublic@interfaceSpringBootConfiguration {}

其实就是一个Configuration配置类,意思是HelloWorldMainApplication最终会被注册到Spring容器中

@EnableAutoConfiguration

开启自动配置功能

以前使用Spring需要配置的信息,Spring Boot帮助自动配置;

@EnableAutoConfiguration通知SpringBoot开启自动配置功能,这样自动配置才能生效。

注解定义如下:

@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public@interfaceEnableAutoConfiguration {}

@AutoConfigurationPackage

自动配置包注解

@Import(AutoConfigurationPackages.Registrar.class)public@interfaceAutoConfigurationPackage {}

@Import(AutoConfigurationPackages.Registrar.class):默认将主配置类(@SpringBootApplication)所在的包及其子包里面的所有组件扫描到Spring容器中。如下

@Order(Ordered.HIGHEST_PRECEDENCE)staticclassRegistrarimplementsImportBeanDefinitionRegistrar,DeterminableImports{@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadata metadata,

BeanDefinitionRegistry registry){//默认将会扫描@SpringBootApplication标注的主配置类所在的包及其子包下所有组件register(registry,newPackageImport(metadata).getPackageName()); }@OverridepublicSetdetermineImports(AnnotationMetadata metadata){returnCollections.singleton(newPackageImport(metadata)); }}

@Import(EnableAutoConfigurationImportSelector.class)

EnableAutoConfigurationImportSelector: 导入哪些组件的选择器,将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中。

1//EnableAutoConfigurationImportSelector的父类:AutoConfigurationImportSelector2@Override3publicString[] selectImports(AnnotationMetadata annotationMetadata) {4if(!isEnabled(annotationMetadata)) {5returnNO_IMPORTS;6}7try{8AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader9.loadMetadata(this.beanClassLoader);10AnnotationAttributes attributes = getAttributes(annotationMetadata);11Listconfigurations= getCandidateConfigurations(annotationMetadata, attributes);12configurations= removeDuplicates(configurations);13configurations=sort(configurations, autoConfigurationMetadata);14Set exclusions = getExclusions(annotationMetadata, attributes);15checkExcludedClasses(configurations, exclusions);16configurations.removeAll(exclusions);17configurations= filter(configurations, autoConfigurationMetadata);18fireAutoConfigurationImportEvents(configurations, exclusions);19returnconfigurations.toArray(newString[configurations.size()]);20}21catch(IOException ex) {22thrownewIllegalStateException(ex);23}24}

我们主要看第11行List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);会给容器中注入众多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。我们跟进去看看

protectedList getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());//...returnconfigurations;}protected Class getSpringFactoriesLoaderFactoryClass() {returnEnableAutoConfiguration.class;}publicstaticfinalStringFACTORIES_RESOURCE_LOCATION ="META-INF/spring.factories";publicstaticList loadFactoryNames(Class factoryClass, ClassLoader classLoader) {StringfactoryClassName = factoryClass.getName();try{//从类路径的META-INF/spring.factories中加载所有默认的自动配置类Enumeration urls = (classLoader !=null? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));List result =newArrayList();while(urls.hasMoreElements()) { URL url = urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(newUrlResource(url));//获取EnableAutoConfiguration指定的所有值,也就是EnableAutoConfiguration.class的值StringfactoryClassNames = properties.getProperty(factoryClassName); result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames))); }returnresult; }catch(IOException ex) {thrownewIllegalArgumentException("Unable to load ["+ factoryClass.getName() +"] factories from location ["+ FACTORIES_RESOURCE_LOCATION +"]", ex); }}

SpringBoot启动的时候从类路径下的 META-INF/spring.factories中获取EnableAutoConfiguration指定的值,并将这些值作为自动配置类导入到容器中,自动配置类就会生效,最后完成自动配置工作。EnableAutoConfiguration默认在spring-boot-autoconfigure这个包中,如下图

最终有96个自动配置类被加载并注册进Spring容器中

J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-xxx.jar中。在这些自动配置类中会通过@ConditionalOnClass等条件注解判断是否导入了某些依赖包,从而通过@Bean注册相应的对象进行自动配置。后面我们会有单独文章讲自动配置的内容

转发关注小编,私信小编“学习”来免费拿走吧~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容