暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringBoot-9-Spring Boot进阶篇:实现配置修改热部署,提升开发效率

446

Spring Boot进阶篇:实现配置修改热部署,提升开发效率

今日目标

掌握SpringBoot正确打包方式

掌握SpringBoot临时配置

了解热部署

1.SpringBoot程序打包和运行

在我们打包的项目是昨天的SSMP项目,打包前在pom.xml中注释一些东西

1.1程序打包

SpringBoot程序是基于Maven创建的,在Maven中提供有打包的指令,叫做package。本操作可以在Idea环境下执行。打包方式:

  • mvn命令打包
mvn package

复制
  • IDEA方式打包

打包后会产生一个与工程名类似的jar文件,其名称是由模块名+版本号+.jar组成的。

1.2程序运行

程序包打好以后,就可以直接执行了。在程序包所在路径下,执行指令。

java -jar 工程包名.jar

复制

出现一下情况:

思考:为什么我们开发可以运行,但是打包后就不能运行了?

这是因为mvn自带的打包插件,没有将依赖的jar包,打入到我们的jar包中

解决方案:

我们要使用SpringBoot项目独有的打包插件spring-boot-maven-plugin
org.springframework.bootspring-boot-maven-plugin

测试运行:

我们发现jar项目可以成功运行,我们再来看看jar包

  • 直观的光从jar包大小我们就可以发现,配置jar包庇不带配置jar包大的多

总结

  1. SpringBoot程序添加配置后会打出一个特殊的包,包含Spring框架部分功能,原始工程内容,原始工程依赖的jar包
  2. 首先读取MANIFEST.MF文件中的Main-Class属性,用来标记执行java -jar命令后运行的类
  3. JarLauncher类执行时会找到Start-Class属性,也就是启动类类名
  4. 运行启动类时会运行当前工程的内容
  5. 运行当前工程时会使用依赖的jar包,从lib目录中查找

2.SpringBoot高级配置

关于配置在SPringBoot基础说过一部分,基础部分的配置总体上来说就是让各位小伙伴掌握配置的格式。比如配置文件如何写啊,写好的数据如何读取啊,都是基础的语法级知识。忘记的小伙伴,可以在看看我之前写的文章Spring Boot快速掌握基础配置技巧

**思考:程序包打好以后,如果配置了服务器的端口是8080。我要启动项目,发现当前我的服务器上已经有应用启动起来并且占用了8080端口,这个时候就尴尬了。难道要重新把打包好的程序修改一下吗?比如我要把打包好的程序启动端口改成80。**

临时属性设置

SpringBoot提供了灵活的配置方式,如果你发现你的项目中有个别属性需要重新配置,可以使用临时属性的方式快速修改某些配置。方法也特别简单,在启动的时候添加上对应参数就可以了。

2.1【--】命令行参数

java -jar day21-springboot-ssmp-0.0.1-SNAPSHOT.jar --server.port=80

复制

运行结果:

如果你发现要修改的属性不止一个,可以按照上述格式继续写,属性与属性之间使用空格分隔。

java -jar day21-springboot-ssmp-0.0.1-SNAPSHOT.jar --server.port=80 --logging.level.root=debug

复制

2.2【-D】虚拟机参数

java -DServer.port=80 -jar day21-springboot-ssmp-0.0.1-SNAPSHOT.jar

复制

注意:

  • 【-D】要放到 -jar 前面,否则参数无效
  • 【--】参数不能放到前面,否则会报错
  • 命令行参数(【--】)与虚拟机参数(-D)同名的,以命令行参数优先
>java -Dserver.port=80 -jar day21-springboot-ssmp-0.0.1-SNAPSHOT.jar  --server.port=81

复制

优先级测试结果:

2.3 IDEA(开发环境)中使用临时属性

临时使用目前是有了,但是上线的时候通过命令行输入的临时属性必须是正确的啊,那这些属性配置值我们必须在开发环境中测试好才行。下面说一下开发环境中如何使用临时属性,其实就是Idea界面下如何操作了。

IDEA代码中获取虚机参数

System.getProperty("server.port")


复制

IDEA代码中获取命令行参数

environment.getProperty("server.port")

复制

完整代码测试:

@SpringBootApplication
@MapperScan("com.zbbmeta.mapper")
public class Day21SpringbootSsmpApplication  implements EnvironmentAware {

    static Environment environment;
    public static void main(String[] args)  {

        System.out.println("虚机: "+System.getProperty("server.port"));
        SpringApplication.run(Day21SpringbootSsmpApplication.classargs);
        //   同名的命令行参数覆盖虚拟机参数
        System.out.println("命令行: "+environment.getProperty("server.port"));

        System.out.println("*****启动成功*****");
    }

    // 注入环境对象
    @Override
    public void setEnvironment(Environment environment) {
        Day21SpringbootSsmpApplication.environment = environment;
    }

}

复制

3.热部署

springboot项目热部署实现原理

基于springboot开发的web工程其实有一个显著的特征,就是tomcat服务器内置了,还记得内嵌服务器吗?服务器是以一个对象的形式在spring容器中运行的。本来我们期望于tomcat服务器加载程序后由tomcat服务器盯着程序,你变化后我就重新启动重新加载,但是现在tomcat和我们的程序是平级的了,都是spring容器中的组件,这下就麻烦了,缺乏了一个直接的管理权,那该怎么做呢?简单,再搞一个程序X在spring容器中盯着你原始开发的程序A不就行了吗?确实,搞一个盯着程序A的程序X就行了,如果你自己开发的程序A变化了,那么程序X就命令tomcat容器重新加载程序A就OK了。并且这样做有一个好处,spring容器中东西不用全部重新加载一遍,只需要重新加载你开发的程序那一部分就可以了,这下效率又高了,挺好。

下面就说说,怎么搞出来这么一个程序X,肯定不是我们自己手写了,springboot早就做好了,搞一个坐标导入进去就行了。

3.1手动启动热部署

【步骤一】:导入开发者工具对应的坐标

<!--        热部署-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

复制

【步骤二】:构建项目,可以使用快捷键激活此功能

对应的快捷键一定要记得

ctrl+F9

复制

以上过程就实现了springboot工程的热部署,是不是挺简单的。不过这里需要把底层的工作工程给普及一下。

重启与重载

一个springboot项目在运行时实际上是分两个过程进行的,根据加载的东西不同,划分成base类加载器与restart类加载器。

  • base类加载器:用来加载jar包中的类,jar包中的类和配置文件由于不会发生变化,因此不管加载多少次,加载的内容不会发生变化
  • restart类加载器:用来加载开发者自己开发的类、配置文件、页面等信息,这一类文件受开发者影响

当springboot项目启动时,base类加载器执行,加载jar包中的信息后,restart类加载器执行,加载开发者制作的内容。当执行构建项目后,由于jar中的信息不会变化,因此base类加载器无需再次执行,所以仅仅运行restart类加载即可,也就是将开发者自己制作的内容重新加载就行了,这就完成了一次热部署的过程,也可以说热部署的过程实际上是重新加载restart类加载器中的信息。

总结

  1. 使用开发者工具可以为当前项目开启热部署功能
  2. 使用构建项目操作对工程进行热部署

思考上述过程每次进行热部署都需要开发者手工操作,不管是点击按钮还是快捷键都需要开发者手工执行。这种操作的应用场景主要是在开发调试期,并且调试的代码处于不同的文件中,比如服务器启动了,我需要改4个文件中的内容,然后重启,等4个文件都改完了再执行热部署,使用一个快捷键就OK了。但是如果现在开发者要修改的内容就只有一个文件中的少量代码,这个时候代码修改完毕如果能够让程序自己执行热部署功能,就可以减少开发者的操作,也就是自动进行热部署,能这么做吗?

3.2 自动启动热部署

自动热部署其实就是设计一个开关,打开这个开关后,IDE工具就可以自动热部署。因此这个操作和IDE工具有关,以下以idea为例设置idea中启动热部署

【步骤一】:设置自动构建项目

打开【File】,选择【settings...】,在面板左侧的菜单中找到【Compile】选项,然后勾选【Build project automatically】,意思是自动构建项目

【步骤二】:允许在程序运行时进行自动构建

使用快捷键【Ctrl】+【Alt】+【Shit】+【/】打开维护面板,选择第1项【Registry...】

在选项中搜索comple,然后勾选对应项即可这样程序在运行的时候就可以进行自动构建了,实现了热部署的效果。

关注:如果你每敲一个字母,服务器就重新构建一次,这未免有点太频繁了,所以idea设置当idea工具失去焦点5秒后进行热部署。其实就是你从idea工具中切换到其他工具时进行热部署,比如改完程序需要到浏览器上去调试,这个时候idea就自动进行热部署操作。

总结

  1. 自动热部署要开启自动构建项目
  2. 自动热部署要开启在程序运行时自动构建项目

思考现在已经实现了热部署了,但是到企业开发的时候你会发现,为了便于管理,在你的程序目录中除了有代码,还有可能有文档,如果你修改了一下文档,这个时候会进行热部署吗?不管是否进行热部署,这个过程我们需要自己控制才比较合理,那这个东西能控制吗?咱

3.3参与热部署监控的文件范围配置

通过修改项目中的文件,你可以发现其实并不是所有的文件修改都会激活热部署的,原因在于在开发者工具中有一组配置,当满足了配置中的条件后,才会启动热部署,配置中默认不参与热部署的目录信息如下

  • /META-INF/maven
  • /META-INF/resources
  • /resources
  • /static
  • /public
  • /templates

以上目录中的文件如果发生变化,是不参与热部署的。如果想修改配置,可以通过application.yml文件进行设定哪些文件不参与热部署操作

spring:
  devtools:
    restart:
      # 设置不参与热部署的文件或文件夹
      exclude: static/**,public/**,config/application.yml

复制

总结

  1. 通过配置可以修改不参与热部署的文件或目录

思考

热部署功能是一个典型的开发阶段使用的功能,到了线上环境运行程序时,这个功能就没有意义了。能否关闭热部署功能呢?

3.4关闭热部署

线上环境运行时是不可能使用热部署功能的,所以需要强制关闭此功能,通过配置可以关闭此功能。

spring:
  devtools:
    restart:
      enabled: false

复制

如果当心配置文件层级过多导致相符覆盖最终引起配置失效,可以提高配置的层级,在更高层级中配置关闭热部署。例如在启动容器前通过系统属性设置关闭热部署功能。

@SpringBootApplication
public class SSMPApplication {
    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled","false");
        SpringApplication.run(SSMPApplication.class);
    }
}

复制

其实上述担心略微有点多余,因为线上环境的维护是不可能出现修改代码的操作的,这么做唯一的作用是降低资源消耗,毕竟那双盯着你项目是不是产生变化的眼睛只要闭上了,就不具有热部署功能了,这个开关的作用就是禁用对应功能。

总结

  1. 通过配置可以关闭热部署功能降低线上程序的资源消耗

如果您觉得本文不错,欢迎关注,点赞,收藏支持,您的关注是我坚持的动力!

原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!


文章转载自springboot葵花宝典,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论