作为Java程序员,理解SpringBoot核心原理吗?

一、前言

使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程。本文的目的就是一步步分析springboot的启动过程,这次主要是分析springboot特性自动装配。

那么首先带领大家回顾一下以往我们的web项目是如何搭建的,通常我们要搭建一个基于Spring的Web应用,我们需要做以下一些工作:

1.pom文件中引入相关jar包,包括spring、springmvc、redis、mybaits、log4j、mysql-connector-java 等等相关jar ...

2.配置web.xml,Listener配置、Filter配置、Servlet配置、log4j配置、error配置 ...

3.配置数据库连接、配置spring事务

4.配置视图解析器

5.开启注解、自动扫描功能 6.配置完成后部署tomcat、启动调试

......

花在搭建一个初始项目,可能一个小时就过去了或者半天救过了,但是用了SpringBoot之后一切都会变得非常便捷,下面我们首先来分析一下SpringBoot的起步依赖以及自动配置。

分享一个我自己的后端技术群,群里自己收集了一些Java架构资料,大家可以进群下载领取群号:680075317,也可以进群一起交流,比如遇到技术瓶颈、面试不过的,大家一些交流学习!

二、起步依赖

1.在我们的pom文件里面引入以下jar:

spring-boot-starter-web包自动帮我们引入了web模块开发需要的相关jar包。

mybatis-spring-boot-starter帮我们引入了dao开发相关的jar包。

spring-boot-starter-xxx是官方提供的starter,xxx-spring-boot-starter是第三方提供的starter。

截图看一下我们的mybatis-spring-boot-starter

可以看出mybatis-spring-boot-starter并没有任何源码,只有一个pom文件,它的作用就是帮我们引入其它jar。

2.配置数据源

stater机制帮我们完成了项目起步所需要的的相关jar包。那问题又来了,传统的spring应用中不是要在application.xml中配置很多bean的吗,比如dataSource的配置,transactionManager的配置 ... springboot是如何帮我们完成这些bean的配置的?下面我们来分析这个过程

三、自动配置------------

1.基于java代码的bean配置

以mybatis为例,在上面的截图中,我们发现mybatis-spring-boot-starter这个包帮我们引入了mybatis-spring-boot-autoconfigure这个包,如下图:

里面有MybatisAutoConfiguration这个类,打开这个类看看有些什么东西。

熟悉@Configuration&、@Bean这两个bean的同学或许已经知道了。这两个注解一起使用就可以创建一个基于java代码的配置类,可以用来替代相应的xml配置文件。

分享一个我自己的后端技术群,群里自己收集了一些Java架构资料,大家可以进群下载领取群号:680075317,也可以进群一起交流,比如遇到技术瓶颈、面试不过的,大家一些交流学习!

@Configuration注解的类可以看作是能生产让Spring IoC容器管理的Bean实例的工厂。

@Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册到spring容器中。

所以上面的MybatisAutoConfiguration这个类,自动帮我们生成了SqlSessionFactory这些Mybatis的重要实例并交给spring容器管理,从而完成bean的自动注册。

2.自动配置条件依赖

从MybatisAutoConfiguration这个类中使用的注解可以看出,要完成自动配置是有依赖条件的。

首先预习一下Springboot是常用的条件依赖注解有:

@ConditionalOnBean,仅在当前上下文中存在某个bean时,才会实例化这个Bean。

@ConditionalOnClass,某个class位于类路径上,才会实例化这个Bean。

@ConditionalOnExpression,当表达式为true的时候,才会实例化这个Bean。

@ConditionalOnMissingBean,仅在当前上下文中不存在某个bean时,才会实例化这个Bean。

@ConditionalOnMissingClass,某个class在类路径上不存在的时候,才会实例化这个Bean。

@ConditionalOnNotWebApplication,不是web应用时才会实例化这个Bean。

@AutoConfigureAfter,在某个bean完成自动配置后实例化这个bean。

@AutoConfigureBefore,在某个bean完成自动配置前实例化这个bean。

所以要完成Mybatis的自动配置,需要在类路径中存在SqlSessionFactory.class、SqlSessionFactoryBean.class这两个类,需要存在DataSource这个bean且这个bean完成自动注册。

进入DataSourceAutoConfiguration这个类,可以看到这个类属于这个包: org.springframework.boot.autoconfigure.jdbc 这个包又属于spring-boot-autoconfigure-2.0.4.RELEASE.jar这个包,自动配置这个包帮们引入了jdbc、kafka、logging、mail、mongo等包。很多包需要我们引入相应jar后自动配置才生效。

3.Bean参数的获取

到此我们已经知道了bean的配置过程,但是还没有看到springboot是如何读取yml或者properites配置文件的的属性来创建数据源的?

在DataSourceAutoConfiguration类里面,我们注意到使用了EnableConfigurationProperties这个注解。

DataSourceProperties中封装了数据源的各个属性,且使用了注解ConfigurationProperties指定了配置文件的前缀。

通过以上分析,我们可以得知:

@ConfigurationProperties注解的作用是把yml或者properties配置文件转化为bean。

@EnableConfigurationProperties注解的作用是使@ConfigurationProperties注解生效。如果只配置@ConfigurationProperties注解,在spring容器中是获取不到yml或者properties配置文件转化的bean的。

通过这种方式,把yml或者properties配置参数转化为bean,这些bean又是如何被发现与加载的?

3.Bean的发现

springboot默认扫描启动类所在的包下的主类与子类的所有组件,但并没有包括依赖包的中的类,那么依赖包中的bean是如何被发现和加载的?

我们通常在启动类中加@SpringBootApplication这个注解,点进去看

实际上重要的只有三个Annotation:

@Configuration(@SpringBootConfiguration里面还是应用了@Configuration)

@EnableAutoConfiguration

@ComponentScan

@Configuration的作用上面我们已经知道了,被注解的类将成为一个bean配置类。

@ComponentScan的作用就是自动扫描并加载符合条件的组件,比如@Component和@Repository等,最终将这些bean定义加载到spring容器中。

@EnableAutoConfiguration 这个注解的功能很重要,借助@Import的支持,收集和注册依赖包中相关的bean定义。

如上源码,@EnableAutoConfiguration注解引入了@AutoConfigurationPackage和@Import这两个注解。@AutoConfigurationPackage的作用就是自动配置的包,@Import导入需要自动配置的组件。

new AutoConfigurationPackages.PackageImport(metadata)).getPackageName()

new AutoConfigurationPackages.PackageImport(metadata)

这两句代码的作用就是加载启动类所在的包下的主类与子类的所有组件注册到spring容器,这就是前文所说的springboot默认扫描启动类所在的包下的主类与子类的所有组件。

那问题又来了,要搜集并注册到spring容器的那些beans来自哪里?

进入 AutoConfigurationImportSelector类,

我们可以发现SpringFactoriesLoader.loadFactoryNames方法调用loadSpringFactories方法从所有的jar包中读取META-INF/spring.factories文件信息。 下面是spring-boot-autoconfigure这个jar中spring.factories文件部分内容,其中有一个key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的值定义了需要自动配置的bean,通过读取这个配置获取一组@Configuration类。

每个xxxAutoConfiguration都是一个基于java的bean配置类。实际上,这些xxxAutoConfiguratio不是所有都会被加载,会根据xxxAutoConfiguration上的@ConditionalOnClass等条件判断是否加载;通过反射机制将spring.factories中@Configuration类实例化为对应的java实列。

到此我们已经知道怎么发现要自动配置的bean了,最后一步就是怎么样将这些bean加载到spring容器。

4.Bean 加载

如果要让一个普通类交给Spring容器管理,通常有以下方法:

1、使用 @Configuration与@Bean 注解

2、使用@Controller @Service @Repository @Component 注解标注该类,然后启用@ComponentScan自动扫描

3、使用@Import 方法

springboot中使用了@Import 方法

@EnableAutoConfiguration注解中使用了@Import({AutoConfigurationImportSelector.class})注解,AutoConfigurationImportSelector实现了DeferredImportSelector接口,

DeferredImportSelector接口继承了ImportSelector接口,ImportSelector接口只有一个selectImports方法。

selectImports方法返回一组bean,@EnableAutoConfiguration注解借助@Import注解将这组bean注入到spring容器中,springboot正式通过这种机制来完成bean的注入的。

分享一个我自己的后端技术群,群里自己收集了一些Java架构资料,大家可以进群下载领取群号:680075317,也可以进群一起交流,比如遇到技术瓶颈、面试不过的,大家一些交流学习!

四、总结

我们可以将自动配置的关键几步以及相应的注解总结如下:

1、@Configuration&与@Bean------>>>基于java代码的bean配置

2、@Conditional-------->>>>>>设置自动配置条件依赖

3、@EnableConfigurationProperties与@ConfigurationProperties->读取配置文件转换为bean。

4、@EnableAutoConfiguration、@AutoConfigurationPackage 与@Import->实现bean发现与加载。

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

推荐阅读更多精彩内容