这部分的学习内容是关于一些名词的解释,这些名词是我在看课过程中,听到或看到却又未曾了解的。因为不理解这些名词的含义,自己在学习过程中常常对某些知识或操作感到困惑。为了解决这些困惑,花了好些时间去搜寻关于这些名词的资料,并整合了起来。
jar包
jar包就是 Java Archive File,顾名思义,它的应用是与 Java 息息相关的,是 Java 的一种文档格式,是一种与平台无关的文件格式,可将多个文件合成一个文件。jar 包与 zip 包非常相似——准确地说,它就是 zip 包,所以叫它文件包。jar 与 zip 唯一的区别就是在 jar 文件的内容中,包含了一个 META-INF/MANIFEST.MF 文件,该文件是在生成 jar 文件的时候自动创建的,作为jar里面的"详情单",包含了该Jar包的版本、创建人和类搜索路径Class-Path等信息,当然如果是可执行Jar包,会包含Main-Class属性,表明Main方法入口,尤其是较为重要的Class-Path和Main-Class。
此外,值得注意的是,因为jar包主要是对class文件进行打包,而java编译生成的class文件是平台无关的,这就意味着jar包是跨平台的,所以不必关心涉及具体平台的问题。
除了.MF以及.class文件之外,jar还能打包静态资源文件如.html、.css以及.js等项目所需的一切,这也就意味着咱们能将自己的项目打成jar,即不管是web应用还是底层框架,都能打成jar包。
有的jar包是可以直接通过 java -jar 指令来执行的。我们都知道,有的类之所以能够执行,是因为它用你有main函数,该函数是程序的入口,同理,可执行的jar包中肯定是有某个.class文件提供了main函数才使得其可执行。那么问题来了,一个jar里面可能存在多个.class文件都有main函数的情况,我怎么知道该执行哪个?其实答案非常简单,就是看前面说的MANIFEST.MF里面的Main-Class属性,它会指定函数入口。
当我们开发了一个程序以后,程序中有很多的类,如果需要提供给别人使用,发给对方一大堆源文件是非常不好的,因此通常需要把这些类以及相关的资源文件打包成一个 jar 包,把这个 jar 包提供给别人使用,同时提供给使用者清晰的文档。这样他人在拿到我们提供的jar之后,就能方便地进行调用。
因此,建议大家在平时写代码搬砖的时候,注意把自己代码的通用部分抽离出来,主键积累一些通用的util类,将其逐渐模块化,最后打成jar包供自己在别的项目或者模块中使用,同时不断打磨jar里面的内容,将其做得越来越容易理解和通用,这样的好处是除了会对你的代码重构能力以及模块抽象能力有很好的帮助之外,更是一种从长期解放你的重复工作量,让你有更多的精力去做其他事情的方式,甚至当你抽象出业内足够通用的jar之后,jar包还能为你带来意想不到的利润。
war包想必大家也都接触过,war是一个可以直接运行的web模块,通常应用于web项目中,将其打成war包部署到Tomcat等容器中。以大家熟悉的Tomcat举例,将war包放置在tomcat根目录的webapps目录下,如果Tomcat成功启动,这个包就会自动解压,就相当于发布了。
除了目录结构外,jar里有的war里也都有。war包是Sun提出的一种web应用程序格式,与jar类似,是很多文件的压缩包。war包中的文件按照一定目录结构来组织。根据其根目录下包含有html和jsp文件,或者包含有这两种文件的目录,另外还有WEB-INF目录。通常在WEB-INF目录下含有一个web.xml文件和一个classes目录,web.xml是这个应用的配置文件,而classes目录下则包含编译好的servlet类和jsp,或者servlet所依赖的其他类(如JavaBean)。通常这些所依赖的类也可以打包成jar包放在WEB-INF下的lib目录下。这也就意味着,war能打包的内容,jar也都可以。有的同学会问了,那既然是这样,直接用jar来替代war不就可以了?诚然,对于现今的应用来讲,主流都是用jar来替代war了。因为war仅服务于Web应用,而jar的涵盖范围更广。目前,war相较于jar的唯一优势在于,就拿tomcat来讲,当tomcat的进程启动之后,将符合规范的war包放在tomcat的webapps目录下的时候,tomcat会自动将war包解压并对外提供web服务,而jar包则不行。
过去由于并未通过微服务将机器资源进行隔离,因此提倡的是一个tomcat实例管理多个java web项目,因此对于java web项目,都提倡将其打成war包然后放置于同一个tomcat的webapps下进行管理,便于资源的统一利用。而随着微服务成为主流,同一台机器上的多个web服务可以通过docker等容器进行隔离,因此我们可以让每个容器都单独运行一个tomcat实例,每个tomcat实例独立运行一个web服务,换句话说,我们可以像springboot一样,将tomcat和web项目打成jar放在一起,以内嵌的方式来启动web服务,使得所有服务的启动方式更优雅和统一,不管是Web服务还是后台服务,均使用java -jar指令来启动。
发布/部署 相关技术概念
1.部署,一般指把应用或者服务“安装”到目标环境中,比如开发,测试或者生产,侧重在“安装”。
2.通常包含 2 种方式,分别为:增量 / 全量部署
3.对比
发布,一般指应用或者服务“交付”给最终用户使用的整个过程及其关联产品。在Google 发布的 the-site-reliability-workbook-next18 中对“发布工程” 是这么描述的:
Release engineering is a term we use to describe all the processes and artifacts related to getting code from a repository into a running production system
在“发布”过程中,“部署”动作紧紧跟随,尤其是在生产环境中。但是他们理应是 2 个完全不同的阶段。通常一个好的“交付”流程,需要把“部署”和“发布”解耦,变成 2 个可以独立控制的阶段。
常见发布技术
配置文件
配置文件本质上是包含成功操作程序所需信息的文件,这些信息以特定方式构成。它们不是在程序中进行硬编码,而是用户可配置的,通常存储在纯文本文件中。
令人惊讶的是,没有关于配置文件应该如何工作的定义标准,或者它们应该是什么样的。这完全取决于程序开发人员的心血来潮。
Linux用户将特别熟悉配置文件,因为许多基本维护任务需要您对其进行编辑。调整Raspberry Pi通常依赖于编辑配置文件。这可能是为了指定要连接到的无线网络或设置图形的RAM数量。但是,配置文件并非Linux独有。有时您可能需要在Windows或macOS中进行编辑。
一些配置文件以开发人员自己设计的格式构造。其他人则使用众所周知的用于构造数据的标准,例如:
一些程序在启动时会加载存储在其配置文件中的信息。同时,其他人会定期检查配置文件以查看其是否已更改。
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
application.properties
语法结构 :key=value
application.yaml
语法结构 :key:空格 value
配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
YAML是 "YAML Ain't a Markup Language" (YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)
这种语言以数据作为中心,而不是以标记语言为重点!
以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,我们来对比下yaml和xml
传统xml配置:
8081
yaml配置:
server:
prot: 8080
说明:语法要求严格!
字面量:普通的值 [ 数字,布尔值,字符串 ]
字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;
k: v
注意:
“ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
比如 :name: "kuang \n shen" 输出 :kuang 换行 shen
'' 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
比如 :name: ‘kuang \n shen’ 输出 :kuang \n shen
对象、Map(键值对)
#对象、Map格式
k:
v1:
v2:
行内写法
student: {name: qinjiang,age: 3}
数组( List、set )
用 - 值表示数组中的一个元素,比如:
pets:
- cat
- dog
- pig
行内写法
pets: [cat,dog,pig]
修改SpringBoot的默认端口号
配置文件中添加,端口号的参数,就可以切换端口;
server:
port: 8082
1.在springboot项目中的resources目录下新建一个文件 application.yml
2.编写一个实体类dog;
package com.example.web.pet; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component public class dog { private String name; public dog() { } public dog(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "dog{" + "name='" + name + '\'' + '}'; } }
3.使用yaml配置的方式进行注入
4.把写好的值注入到类中
5. 去测试类中测试一下
运行结果成功:
profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本
如:
application-test.properties 代表测试环境配置
application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件
我们需要通过一个配置来选择需要激活的环境:
spring.profiles.active=dev
比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试。启动SpringBoot,就可以看到已经切换到dev下的配置了。
运行结果如下
若添加配置文件 application-test.properties 并执行spring.profiles.active=test,结果便为
和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了 !
运行结果如下
注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!
解决思路:引入dog类
2.dog类测试结果全为null
解决思路:查找dog类,看是否缺少构造函数、set、get或toString函数等,并补齐缺少的函数。
package com.example.web.pet; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; //dog和其子类必须包含:无参、有参构造、set、get方法 //否则打印值为null 或 运行报错 @Component @ConfigurationProperties(prefix = "dog") public class dog { private String name; public dog() { } public dog(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "dog{" + "name='" + name + '\'' + '}'; } }
解决思路:打开报错提示的网站,将其中的依赖导入到pom.xml中
继续看教学视频学习springboot