springboot启动太慢优化

需求缘起:有人在【springboot】微信公众号问:springboot启动慢的问题何时有个分享就好了,谢谢。粉丝的问题还是要认真的回答的。

 

       我们先看看本节的大纲:

(1)组件自动扫描带来的问题(@SpringBootApplication);
(2)如何避免组件自动扫描带来的问题(不使用@ SpringBootApplication);
(3)引发的问题——无法扫描组件;
(4)千古红楼只一梦,竹篮打水一场空;
(5)debug debug,bug bug更健康;
(6)分析Positive matches和Negative matches;
(7)再次优化配置信息;
(8)总结

 

接下来我们一起探讨下每个问题。

(1)组件自动扫描带来的问题(@SpringBootApplication);

       我们在第一篇博客就介绍了,我们默认情况下,我们会使用@SpringBootApplication注解来自动获取应用的配置信息,但这样也会带来一些副作用。使用这个注解后,会触发自动配置(auto-configuration)和组件扫描(component scanning),这跟使用@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解的作用是一样的。这样做给开发带来方便的同时,会有以下的一些影响:

(a)会导致项目启动时间变长(原因:加载了我们不需要使用的组件,浪费了cpu资源和内存资源)。当启动一个大的应用程序,或将做大量的集成测试启动应用程序时,影响会特别明显。

(b)会加载一些不需要的多余的实例(beans)。

(c)会增加CPU消耗和内存的占用。

 

(2)如何避免组件自动扫描带来的问题(不使用@ SpringBootApplication);

       本着有问题就要解决的心态,针对以上的问题,我们要怎么解决呢?很明显,既然@SpringBootApplication加载了一些不必要的配置,那么我们想是否可以就加载我们自己指定的配置呢?我们的思路不使用@SpringBootApplication,并且不使用@ComponentScan注解(此注解会自动扫描我们注解了@Controller,@Service的注解的类,加载到Spring IOC容器中),然后我们使用@Configuration和@EnableAutoConfiguration进行配置启动类,代码如下:

package com.kfit.spring_boot_performance;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

 

import com.kfit.spring_boot_performance.controller.HelloController;

 

/**

 * @author Angel --守护天使

 * @version v.0.1

 * @date 2017年3月11日

 */

//移除 @SpringBootApplication and @ComponentScan, 用 @EnableAutoConfiguration 来替代

@Configuration

@EnableAutoConfiguration

public class App {

   

   

    public static void main(String[] args) {

       SpringApplication.run(App.class, args);

    }

}

 

(3)引发的问题——无法扫描组件;

我们正要为我们的代码改良庆幸的时候,我们发现问题来了。启动之后,访问我们编写的访问页面/index,出现错误:There was an unexpected error (type=Not Found, status=404).

这是由于什么引起的呢?还记得我们刚刚介绍的@ComponentScan注解嘛,启用这个注解Spring才能够进行自动组件的扫描,否则无法扫描到我们编写的组件类。那么问题来了,怎么办呢?问题的解决就是:显式进行配置。

       注入代码如下(假设我们写的类是HelloController,在这里博主直接写在App.java启动类进行注入):

   @Bean

    public HelloController helloController(){

        return new HelloController();

    }

在以上的代码中用 @Bean 注解明确显式配置,以便被 Spring 扫描到。

在重新启动之后,我们就可以正常访问/index页面了。

       到这里肯定就会有人会说:那这样的话,不是会增加我们的编码量。我只能说:你既要加载快,又要不编码,博主实在不知道怎么办了。凡事有利有弊,自己权衡利弊。

 

(4)千古红楼只一梦,竹篮打水一场空

       有人不相信,这个真的能启动更快吗,于是乎就编码进行测试。哈哈,露馅了,还是一样启动的跟蜗牛一样慢。那为什么是这样呢?为什么我们研究了半天,最终却是:千古红楼只一梦,竹篮打水一场空。

       聪明的读者,会注意到我们提到:@SpringBootApplication注解的作用跟@EnableAutoConfiguration注解的作用是相当的,那就意味着它也能带来上述的问题。要避免这些问题,我们就要知道我们的组件列表是哪些?

 

(5)debug debug,bug bug更健康

       我们在上面说了,我们的问题就是如何知道我们的组件列表是哪些?这时候debug就隆重登场了,鼓掌欢迎debug先生上场。

 

       请问debug先生:在此时此刻您有什么获奖感言?

       debug先生:经历了慢慢人生,我终于发现我的价值了。在这里我要感谢CCTV、感谢MTV、感谢可口可乐,感谢非常可乐、感谢加多宝、感谢王老吉、感谢主办方SpringBoot,让我有机会在这个舞台跟大家见面。谢谢你们,我一定不会让大家失望的。

 

       好了,废话不多说了,我们先看看如何使用debug呢?

第一种情况:使用spring-boot:run启动方式

       这种情况的话,完整的运行代码是:

       spring-boot:run -Ddebug

 

第二种情况:使用Run As —— Java Application启动方式

       这种情况的话,配置VM参数即可,具体操作如下:

【右键】——【Run As】——【Run  Configurations…】——【选择Arguments】——【VM arguments】中加入:【-Ddebug】。

 

这时候在启动的时候,我们就能看到控制台打印出了一些我们平时没看到过的日志信息。

=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------

DispatcherServletAutoConfiguration matched
- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
//此处省略剩下的打印信息…

 

 

(6)     分析Positive matches和Negative matches;

       在打印信息里,我们有必要先了解下这里的一些知识:

(a) Positive match:累出匹配到对应类的配置项。
(b) Negative match:不包括某个配置项的原因。

 

现在以DataSourceAutoConfiguration举例说明:

(a)@ConditionalOnClass表示对应的类在classpath目录下存在时,才会去解析对应的配置文件,对于DataSourceAutoConfiguration来说就是指:只有javax.sql.DataSource和org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType类都存在时,就会配置对应的数据库资源。
(b)@ConditionalOnMissingClass表示对应的类在classpath目录下找不到。
(c)OnClassCondition用于表示匹配的类型(postive or negative)。
OnClassCondition是最普遍的浏览探测条件,除此之外,Spring Boot也使用别的探测条件,如:OnBeanCondition用于检测指定bean实例存在与否、OnPropertyCondition用于检查指定属性是否存在等等。
符合negative match代表一些配置类(xxxConfiguration之类的),它们虽然存在于classpath目录,但是修饰它们的注解中依赖的其他类不存在。

 

 

(7)     再次优化配置信息

       根据上面的理论知识,我们只需要在启动的时候,显式地引入这些组件,拷贝Positive matches中列出的信息:

DispatcherServletAutoConfiguration 

EmbeddedServletContainerAutoConfiguration 

ErrorMvcAutoConfiguration 

HttpEncodingAutoConfiguration 

HttpMessageConvertersAutoConfiguration 

JacksonAutoConfiguration 

JmxAutoConfiguration 

MultipartAutoConfiguration 

ServerPropertiesAutoConfiguration 

PropertyPlaceholderAutoConfiguration 

ThymeleafAutoConfiguration 

WebMvcAutoConfiguration 

WebSocketAutoConfiguration

 

然后来更新项目配置,显式地引入这些组件,引入之后,再运行一下应用确保没有错误发生:
@Configuration

@Import({

        DispatcherServletAutoConfiguration.class,

        EmbeddedServletContainerAutoConfiguration.class,

        ErrorMvcAutoConfiguration.class,

        HttpEncodingAutoConfiguration.class,

        HttpMessageConvertersAutoConfiguration.class,

        JacksonAutoConfiguration.class,

        JmxAutoConfiguration.class,

        MultipartAutoConfiguration.class,

        ServerPropertiesAutoConfiguration.class,

        PropertyPlaceholderAutoConfiguration.class,

        ThymeleafAutoConfiguration.class,

        WebMvcAutoConfiguration.class,

        WebSocketAutoConfiguration.class,

})

public class App {

 

       在上面的代码中,我们可以删掉我们不需要的组件信息,来挺高应用的性能,比如在项目中没有使用Jmx和WebSocket功能的话,那么我们就可以删除JmxAutoConfiguration.classWebSocketAutoConfiguration.class

删除掉之后,再次运行项目,确保一切正常。

 

(8)总结

       在本篇文章中我们介绍了如何加速spring boot快速启动,主要的思路就是废弃@SpringBootApplication显式的引入我们所需要的组件。

       下节预告:介绍高性能Web服务器Undertow,在下一篇介绍如何替换Tomcat使用Undertow进行内存优化。

转载于:https://www.cnblogs.com/cmfwm/p/7943756.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467222.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

绑定字符串

Bind("BARAS","{0:F0}")CutString1(DataBinder.Eval(Container.DataItem,"title").ToString(),12)((bool)DataBinder.Eval(Container.DataItem,"IfShow"))?"Yes":"No" 使用 Eval 方法 Eval 方法可计算数据绑定控…

ajax封装 使用,AJAX封装类使用指南

AJAX说起来感觉很难,但是把他封装起来你会发现使用起来很简单了,当然也是简单的应用了,譬如留言板的应用等,这里首先,先送大家一个礼物那就是封装好的AJAX的类,下载地址http://xiazai.jb51.net/201412/yuan…

Linux cpuidle framework

背景Kernel版本:4.14ARM64处理器使用工具:Source Insight 3.5, Visio1. 介绍在Linux OS中,Idle进程的运行会让CPU进入cpuidle状态。当没有其他进程处于运行状态时,Scheduler会选择Idle进程来运行,此时CPU无…

Crystal 语法概述[转]

Crystal 语法概述创建公式时,可以选择使用 Crystal 语法或 Basic 语法。语法规则用于创建正确的公式。几乎任何使用某种语法编写的公式都可以使用另一种语法来编写。报表可以包含使用 Crystal 语法的公式,也可以包含使用 Basic 语法的公式。有关是使用 C…

上传源文件至虚拟服务器,C# 通过WebService上传视频文件到服务器虚拟机下源码...

【实例简介】请参考:http://blog.csdn.net/dwj901125/article/details/23701063这里有相当详尽的实现过程。【实例截图】【核心代码】WebServiceTest├── WebServiceTest│ ├── Backup│ │ ├── StateGrid95598│ │ │ ├── Properties│ …

Linux利器:QEMU!用它模拟开发板能替代真开发板?

不想错过我的推送,记得右上角-查看公众号-设为星标,摘下星星送给我!QEMU,搞嵌入式开发的一定不陌生,最近各大群里都讨论疯了,说它是Linux利器一点也不夸张。它是一款知名的而且开源的模拟器(官网…

前端模块化(二):模块化编程

所谓的模块化编程就是封装细节,提供使用接口,彼此之间互不影响,每个模块都是相互独立,实现某一特定的功能。如果其他模块想调用的时候,可以暴露我们所希望对外的公开的方法与数据。 1、函数写法 function f1(){ var va…

ASP.NET AJAX - Timer控件之摆放位置的影响

ASP.NET AJAX所提供的Timer 控件是一个服务器控件&#xff0c;它能够定时引发全网页回传&#xff0c;当然&#xff0c;在搭配了UpdatePanel 控件之后&#xff0c;就可以定时引发异步回传并局部更新UpdatePanel 控件的内容。<?xml:namespace prefix o />在此要请大家注意…

CPU怎么认识代码的?

# 语言这个东西&#xff1f;首先说明下&#xff0c;我们正常使用的python、C、C语言等等&#xff0c;我们自己能读得懂的语言&#xff0c;包括汇编语言&#xff0c;CPU都是不认识的&#xff0c;CPU 只认识一种语言&#xff0c;那就是 机器语言&#xff0c;也就是我们很多人&…

ajax 五种状态,ajax的五种状态

ajax的五种状态(readyState )0 &#xff0d; (未初始化)还没有调用send()方法1 &#xff0d; (载入)已调用send()方法&#xff0c;正在发送请求2 &#xff0d; (载入完成)send()方法执行完成&#xff0c;已经接收到全部响应内容3 &#xff0d; (交互)正在解析响应内容4 &#x…

nodeJs的学习之路(1)

一 什么是nodeJs nodeJs是一个后端技术&#xff0c;研究web应用的开发模式&#xff0c;能够开发一些简单的服务器&#xff0c;学会操作数据库等等。官方解释就是&#xff1a;nodeJs是基于谷歌v8引擎的javascript运行环境 nodeJs使用了一个事件驱动&#xff0c;非非阻塞式I/O模型…

u盘病毒之tel.xls.exe

系统症状每次双击盘符出现一个新窗口windows任务管理器出现了一个Excel的程序鼠标右键点盘符出现"Auto"字样无法显示隐藏文件无法 取消或者钩选 隐藏已知文件类型的扩展名 样本信息File size: 49152 bytes MD5: d88f7c6c15585404c30c92a11c429c36 SHA1: af2120915a1e…

节日才需要快乐吗?

---- 当然需要天天快乐2020年的国庆和中秋是挺特别的&#xff0c;也是国庆&#xff0c;也是中秋&#xff0c;而且今天还能看NBA总决赛助兴。这么愉快的节日&#xff0c;祝我们的国家繁荣昌盛&#xff0c;国泰民安&#xff0c;也祝大家中秋快乐&#xff0c;当然中秋后也需要快乐…

大屏幕服务器无信号,关于思讯互动平台大屏幕使用过程中错误的排查

关于思讯互动平台大屏幕使用过程中错误的排查一、错误原因分析 原因具体内容浏览器原因包括但不限于浏览器不兼容、浏览器设置出问题、浏览器安装了不明插件、浏览器有缓存电脑原因电脑性能太差、开启了太多程序进程、电脑系统老旧网络原因断网、多人共同占用网络导致网速过慢人…

我在富士康13年

以下是一个读者朋友的日记---- ???? 有点恨铁不成钢的感觉这个读者跟我一样的年纪&#xff0c;都是89年&#xff0c;好吧&#xff0c;说到这里突然觉得又马上要老一岁了&#xff0c;因为小云跟我说&#xff0c;我马上就要过生日了&#xff0c;我从来就记不清自己的生日&…

《Android源码设计模式》--装饰模式

No1&#xff1a; Activity继承于ContextThemeWrapper&#xff0c;继承于ContextWrapper&#xff0c;继承于Context。 No2&#xff1a; Context中方法的所有实现均由ContextImpl类承担。 No3&#xff1a; 启动一个Activity需要3个非常重要的对象&#xff1a;Application、Contex…

域名服务器的配置文档,dns域名服务器的配置

dns域名服务器的配置 内容精选换一换使用mount命令挂载文件系统到云服务器&#xff0c;云服务器系统提示timed out。原因1&#xff1a;网络状态不稳定。原因2&#xff1a;网络连接异常。原因3&#xff1a;云服务器DNS配置错误&#xff0c;导致解析不到文件系统的域名&#xff0…

ASP无组件上传带进度条

<%LANGUAGE"VBSCRIPT" CODEPAGE"936"%><%Option Explicit%><% 带进度条的ASP无组件断点续传下载简介&#xff1a; 1)利用xmlhttp方式 2)无组件 3)异步方式获取&#xff0c;节省服务器…

广东阳西的小城生活

国庆放假&#xff0c;回小云老家&#xff0c;广东阳江阳西县。我们是昨天下午5点出发&#xff0c;晚上11点到家&#xff0c;刚好错开拥堵高峰&#xff0c;不过在沿江高速上川岛附近还是遇到了交通堵塞&#xff0c;一直缓缓前行&#xff0c;等到我们通过那个事故点的时候&#x…

React Native之箭头函数和延展操作符(...)

箭头函数 在我们学习React Native的过程中&#xff0c;我们经常会遇到">"这样形式的书写&#xff0c;如下&#xff1a; import React, {Component} from react import {AppRegistry, StyleSheet, View, Text, TouchableOpacity} from react-nativeclass RN_Arrow_…