通过前面章节的学习,我们掌握了使用Spring Boot框架进行实际应用开发的方法。在使用Spring Boot 的过程中,我们时常会为一些看似简单,但实际上蕴藏了强大功能的实现而惊呼,下面就让我们来揭开它的神秘面纱,做到知其然,进而知其所以然。在认识Spring Boot 的实现原理之后,我们在使用某些功能时,就能够做到心中有数,从而更好地使用它。

1 Spring Boot主程序的功能

代码清单10-1是Spring Boot应用的一个典型主程序,它看起来非常简单,使用了一个同样看起来非常简单的注解@SpringBootApplication,并用一个非常普通的main方法运行SpringApplication的 run方法。这个简单的主程序将会加载一个应用所需的所有资源和配置,最后启动一个应用实例。

代码清单10-1Spring Boot应用主程序

1.1SpringApplication的run方法

Spring Boot的主程序有什么神奇的地方呢?可以从 SpringApplication的run方法说起,这是应用主程序开始运行的方法,它的源代码如代码清单10-2所示。这个方法让我们能够看清楚Spring Boot的一切秘密所在,它首先开启一个SpringApplicationRun-Listeners监听器,然后创建一个应用上下文ConfigurableApplicationContext,通过这个上下文加载应用所需的类和各种环境配置等,最后启动一个应用实例。

代码清单10-2SpringApplication中run的源代码

如果你使用过Spring框架,就会更加清楚这种加载应用的实现机制。在Spring 中,

加载一个应用,主要是通过一些复杂的配置来实现的。这样看来,Spring Boot 只不过是把这些本来由程序员做的工作,事先帮我们实现罢了。

1.2创建应用上下文

一个应用能够正常运行起来,需要一些环境变量、各种资源和一些相关配置等,从创建应用上下文ConfigurableApplicationContext的源代码中,我们可以看到这种实现机制,如代码清单10-3所示。其中,this.load (context, sources.toArray (new Object[sources.size(]))将调用BeanDefinitionLoader来加载应用定义的和需要的类及各种资源。

代码清单10-3创建应用上下文——createAndRefreshContext的源代码

1.3自动加载

在BeanDefinitionLoader 中,有一个load (Class> source)方法用来加载类定义,如代码清单10-4所示。这里的source就是代码清单10-1中定义的Application.class。在程序中通过isComponent检查是否存在注解,如果有注解,则调用注解相关的类定义。这样注解@SpringBootApplication将被调用,它不但会导入一系列自动配置的类,还会加载应用中一些自定义的类。

代码清单10-4BeanDefinitionLoader 中 load(Class>source)源代码

从以上分析可知,一个简单的Spring Boot主程序,通过运行一个run方法,就将引发一系列复杂的内部调用和加载过程,从而初始化一个应用所需的配置、环境、资源及各种类定义等。特别是导入了一系列自动配置类,实现了强大的自动配置功能,这是Spring Boot框架最引人注目的地方。

2.Spring Boot自动配置原理

所有的自动配置都是从注解@SpringBootApplication引人的,我们来看看它的源代码,就一切都明白了。如代码清单10-5所示,注解@SpringBootApplication其实又包含了三个非常重要的注解,即@Configuration、@EnableAutoConfiguration和@ComponentScan,其中注解@EnableAutoConfiguration就是启用自动配置的,并将导入一些自动配置的类定义,注解@ComponentScan将扫描和加载应用中的一些自定义的类。

代码清单10-5SpringBootApplication源代码

2.1自动配置的即插即用原理

EnableAutoConfiguration最终会导入一个自动配置的类列表,如代码清单10-6所示。列表中的自动配置类很多,这些配置类中大都将被导入,并处于备用状态中,这如同电器中准备了一些插槽一样,即实现了即插即用的原理。这样,当项目中引入了相关的包时,相关的功能将被启用。例如在项目的Maven管理中配置了Redis 的引用,那么Redis的功能将被启用,这时启动应用,程序将尝试读取有关Redis的配置信息。

代码清单10-6自动配置类部分列表

2.2自动配置的约定优先原理

在自动配置中加载一个类的配置时,首先读取项目中的配置,只有项目中没有相关配置才启用配置的默认值,这就是自动配置的约定优先原理。代码清单10-7是Thymeleaf配置类的源代码,如果在项目的配置文件中没有配置spring.thymeleaf的相关参数,就使用Thymeleaf 的默认配置,默认配置将使用templates作为HTML文件的存放路径。在前面章节使用Thymeleaf的实例中,就是使用了这个默认配置。

代码清单10-7Thymeleaf 配置源代码

3.提升应用的性能

Spring Boot 的自动配置在给我们提供很大便利的同时,难免会有一些副作用,即增加了应用启动的时间、一些内存和CPU的消耗等。如果应用对性能要求很高,就可以根据自动配置的原理,使用一些技巧进行优化。

3.1更改加载配置的方式

如果能清楚一个应用需要哪些配置,就能够更改加载配置的方式,即不使用自动配置,而是改为指定加载一些应用所需的配置。

为了弄清楚一个应用需要加载哪些配置,可以使用Maven调试的方式来启动一个应用,然后从控制台的输出日志中,确定哪些是这个应用需要加载的配置类。下面使用第1章中简单的实例项目来说明这种操作。

首先,在IDEA的Edit Configuration中增加一个Maven配置,工作路径选择项目根目录,在命令行中输入: spring-boot:run -Ddebug,并把配置保存为debug,如图10-1所示。

以 Debug方式运行debug配置,启动应用,然后在控制台中找出Positive matches的类,如代码清单10-8所示。Positive matches就是这个应用所需加载的一些配置类。

代码清单10-8加载自动配置的Positive matches类列表

通过整理后,得出这个应用需要加载的配置类列表,如代码清单10-9所示。

代码清单10-9整理后的Positive matches类列表

根据这个配置类加载列表,就可以在主程序中使用注解@Configuration来代替注解@SpringBootApplication,并用注解@Import 指定需要加载的配置类,经过更改后的应用主程序如代码清单10-10所示。

代码清单10-10主程序中指定加载的配置类

3.2将Tomcat换成Jetty

另外,为了提高应用的性能,还可以更改默认使用的Tomcat插件,换成更加小巧的Jetty插件。例如,代码清单10-11是在工程的Maven配置中排除引用默认的Tomcat,转而引用Jetty的依赖。

代码清单10-11使用Jetty的 Maven配置

4.性能对照测试

通过上面一些改造之后,可以对照测试一下,看看效果如何。打开IDEA的 EditConfiguration对话框,增加一个Application配置,工作目录选择工程根目录,并选择工程主程序,然后在VM options 中输入如下配置参数:

-Dcom.sun.management.jmxremote -Dcom.sun.management .jmxremote.port="9004"-Dcom.sun. management .jmxremote.authenticate="false"

-Dcom . sun . management . jmxremote.ssl= "false"

这样配置的目的,是让我们可以使用JConsole来观察应用运行的各项性能指标。配置完成后的效果如图10-2所示。

对比改造前后的两种情况,改造后应用的启动时间有所加快。改造前启动应用的时间如下所示:

started Application in 3.171 seconds (JVM running for 4.941)

改造后启动应用的时间如下:

started Application in 2.957 seconds (JVM running for 5.869)

应用启动后,使用JConsole新建一个连接,可以观察应用运行的各项性能指标。根据上面配置的参数,可以在远程进程中输入 localhost:9004,然后单击“连接”按钮,如图10-3所示。

改造前后的两种运行情况对照如图10-4所示。图中各项指标处于0的位置是中间停止时的状态,从图中可以看出,改造后内存的使用量明显减少了,CPU的占用也有所改善,加载的类减少了一点,并不是很明显。从总体上来说,性能是有所改善了。

5.小结

本章分析了Spring Boot应用主程序的内部实现的一些源代码,及其功能强大的自动配置的实现原理,使我们认识了神奇的Spring Boot 的内部实现机制,在看似简单的调用中,其实包含着复杂的内部实现。这就不难理解,为什么使用Spring Boot可以那么简单,这是因为它把一些复杂的实现,都事先帮我们做好了。

基于对Spring Boot 的深入了解,特别是认识自动配置的实现原理之后,就可以改造一个应用加载配置的方式,从而达到提高性能的目的。虽然这种改造的作用并不是特别明显,但是不管怎样,至少能帮助我们加深对Spring Boot的理解。

通过前面章节的应用实例,我们也知道,在 Spring Boot中使用数据库也是非常简单的,那么Spring Boot在使用数据库方面,其内部实现又是怎样一个引人入胜的工程呢?下一章将分析Spring Boot在使用数据库方面的一些实现原理,看看它又有什么神奇之处。

springboot自动配置原理_今日份学习之Spring Boot自动配置实现原理相关推荐

  1. redis spring 切面缓存_今日份学习: Spring中使用AOP并实现redis缓存?

    笔记 在Spring中如何使用AOP? Spring是如何切换JDK动态代理和CGLIB的? spring.aop.proxy-target-class=true (在下方第二个链接中,原生doc中提 ...

  2. 超完整!Springboot整合redis集群(Sentine),spring boot自动配置集成redis集群(Sentine)

    1.添加maven依赖 注意maven版本依赖,版本要相互匹配,如不知道如何查看相对应的版本时,可进入博主主页查看博主上一篇博文. <parent><groupId>org.s ...

  3. springboot转发http请求_Spring Boot2 系列教程(八)Spring Boot 中配置 Https

    https 现在已经越来越普及了,特别是做一些小程序或者公众号开发的时候,https 基本上都是刚需了. 不过一个 https 证书还是挺费钱的,个人开发者可以在各个云服务提供商那里申请一个免费的证书 ...

  4. springboot内存占用大_小宇宙爆发!Spring Boot 节省95%内存占用

    GraalVM[1] 是一种高性能的虚拟机,它可以显著的提高程序的性能和运行效率,非常适合微服务.最近比较火的 Java 框架 Quarkus[2] 默认支持 GraalVM 下图为 Quarkus ...

  5. GPS 校验和 代码_今日份∣学习(三菱-菱云系列)电梯故障代码表

    作为电梯人, 我们不仅要从培训中学习, 更要从实践中总结窍门和技巧, 这样,见的多了, 遇到问题才不会慌张,才能得心应手, 想要成为"电梯高手", 还需要我们下功夫,加油吧! 故障 ...

  6. Spring Boot自动配置原理分析

    一.写在前面 随着时间的迁移Spring Boot 越来越多的出现在Java 后端程序员的视野中,Spring Boot 之所以会那么流行,很大的一个原因是自身集成了很多的Bean,简化了传统Srin ...

  7. 学习第三篇:【SpringBoot-Labs】芋道 Spring Boot 自动配置原理

    本周(8.21-8.27)将学习芋道 Spring Boot的以下文章: 8.21: 快速入门 8.22:Spring Boot 自动配置原理 .Jar 启动原理 8.23:调试环境. 热部署入门.消 ...

  8. Spring Boot自动配置原理

    要了解Spring Boot的自动配置首先我需要先了解Spring Boot的两个机制,一个是配置文件如何进入到系统变成属性,二是如何将这些属性加入到容器中. 首先我们需要有一个组件,这个组件中的属性 ...

  9. Spring Boot自动配置原理、实战

    Spring Boot自动配置原理 Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射. org.s ...

最新文章

  1. 三星手机怎么恢复删除的图片_手机相册照片突然删除了怎么恢复?这个方法好用...
  2. “正则表达式”应当称为“规则表达式”
  3. 不越狱无硬件,轻松搞定iPhone投影与录屏
  4. 在Linux中如何查看文件的修改日期
  5. aws 删除ec2实例_如何在AWS EC2实例上部署Spring Boot应用程序
  6. cocos2dx动画Animation介绍
  7. 中国蔬菜汤市场趋势报告、技术动态创新及市场预测
  8. GPU-Z:显卡体质、显卡各传感器实时状态的查看
  9. 2015年总结与2016年目标
  10. 局域网内网关欺骗获取网站密码
  11. 短视频解析去水印在线 伪原创视频如何搬运
  12. Python一个命令开启http下载服务器
  13. Echarts 实现 设备运行状态图 工业大数据展示
  14. 人生如逆旅,我亦是行人。
  15. 大厂算法面试之leetcode精讲4.贪心
  16. c语言程序实现进程的管道通信,C 进程间通信--命名管道通信代码实现及其原理图示...
  17. 51单片机printf重定向
  18. 利用conda安装包、卸载包、升级包、查看包信息等操作
  19. Android动画实战-仿简聊App动画菜单
  20. 静态路由配置(不会配静态路由,看这里就够了!)

热门文章

  1. c mysql清理日志文件_MySQL 一般查询日志或者慢查询日志历史数据的清理
  2. c++ 写文件怎么让0x00不被识别成结束符_使用docker-copyedit工具删除镜像中不需要的环境变量和VOLUME...
  3. python自动化测试-python自动化之(自动化测试报告)
  4. python 菜鸟-Python IDE
  5. 0基础学python要多久-怎么自学python,大概要多久?
  6. python 在线培训费用-在线Python编程培训哪家机构比较好?
  7. python新手入门代码-[代码全屏查看]-新手初学Python实现某论坛自动签到功能
  8. Nuance语音识别技术及解决方案
  9. get post请求区别_网页常见的两种请求方式Get和Post
  10. BOM——window对象