前言

今天熟悉项目代码时意识到一个问题:我对jsp、springmvc、spring、mybatis、jetty、maven等知识陌生了!虽然前端页面也需要写,而且也有点生疏,不过之前对于html、css、js、jquery、ajax等知识积累不多,所以也没感觉到有什么不妥。

但是,后端知识变得陌生,让我不得不反思。我想造成这种情况的原因有两个:一是最近一直在使用springboot、spring data jpa等框架,它们封装的太多,导致我都忘记了原始的样子。二是我原本就积累不足,熟练度不够。

关于jsp知识忘记的原因:是因为最近一直在做前后端分离的项目,我只是提供后端接口,我的任务到controller就打住了,前端样式更是不需要关心。

基于这个问题,我认为应该回顾下Java基础知识,对整个体系做一个简单的梳理,加强理解,提高熟练度。

JavaSE

我从学习Java开始,第一个接触到的相关知识是JDK,Java Development Kit,它是Sun公司针对Java开发人员发布的免费软件开发工具包(SDK,Software development kit),自从Java推出以来,JDK已经成为使用最广泛的Java SDK。作为Java语言的SDK,普通用户并不需要安装JDK来运行Java程序,而只需要安装JRE(Java Runtime Environment)。而程序开发者必须安装JDK来编译、调试程序。JDK包含了一批用于Java开发的组件,其中包括:

  • javac:编译器,将后缀名为.java的源代码编译成后缀名为“.class”的字节码。
  • java:运行工具,运行.class的字节码。
  • jar:打包工具,将相关的类文件打包成一个文件。
  • javadoc:文档生成器,从源码注释中提取文档,注释需匹配规范。
  • jdb debugger:调试工具。
  • jps:显示当前java程序运行的进程状态。
  • javap:反编译程序。
  • appletviewer:运行和调试applet程序的工具,不需要使用浏览器。
  • javah:从Java类生成C头文件和C源文件。这些文件提供了连接胶合,使Java和C代码可进行交互。
  • javaws:运行JNLP程序。
  • extcheck:一个检测jar包冲突的工具。
  • apt:注释处理工具。
  • jhat:java堆分析工具。
  • jstack:栈跟踪程序。
  • jstat:JVM检测统计工具。
  • jstatd:jstat守护进程。
  • jinfo:获取正在运行或崩溃的java程序配置信息。
  • jmap:获取java进程内存映射信息。
  • idlj:IDL-to-Java编译器。将IDL语言转化为java文件。
  • policytool:一个GUI的策略文件创建和管理工具。
  • jrunscript:命令行脚本运行。

JDK中还包括完整的JRE(Java Runtime Environment)。JRE包括了用于产品环境的各种库类,如基础类库rt.jar,以及给开发人员使用的补充库,如国际化与本地化的类库、IDL库等等。下面的图很形象,可以帮助理解JDK和JRE、开发工具和操作系统之间的关系。另外,JDK8的APIs请移步官网:https://docs.oracle.com/javase/8/docs/api/
JDK图示_副本_副本.jpg

JDK更细致一点的描述可参考下面的图:
image.png

JDK的理论知识到此结束。作为Java开发人员,首先需要下载和安装JDK。

  • 下载。最近使用Java8版本的的JDK,那这次就下载JDK8,下载地址:链接太长。不过,这次也点了下Java EE的目录,里面也有Java EE SDK,通常我使用的都是Java SE SDK,没有了解过Java EE SDK。据了解,Java EE SDK比 Java SE SDK 多了一些工具包,主要偏向于开发企业级应用时要用到的包,包括Servlet容器等。对于通常使用的Java SE SDK,也可以用于开发企业级应用,额外的功能由第三方功能包来支持,比如Tomcat、Spring等。

下载界面.png

  • 安装。跟普通的windows程序安装步骤相同,双击即可,安装过程中的配置项我通常选择默认选项。

    1. ![image.png](https://cdn.nlark.com/yuque/0/2019/png/111066/1555747385157-ed0c3e5c-95e9-443e-bc31-c4466872c3b9.png#align=left&display=inline&height=131&name=image.png&originHeight=131&originWidth=102&size=18848&status=done&width=102)

安装完成后,就可以利用它来开发和运行Java程序了。首先写一个Hello World程序体验一把。

  • 在目录D:\JavaProject下新建text文件,输入以下内容,将扩展名改为java。

    1. public class Hello{
    2. public static void main(String[] args){
    3. System.out.print("Hi,java.");
    4. }
    5. }
  • 编译+执行。

    image.png

至此,第一个Java程序完成了。不过,还有一点可以改进:每次编译和执行都需要输入全路径比较麻烦。
解决方案:将路径写到到环境变量。环境变量的作用就是方便系统程序的调用,比如我想打开计算器,就可以在命令行中输入calc,操作系统会遍历环境变量的所有路径来寻找calc.exe并打开它。如果在环境变量中配置了javac.exe和java.exe的路径,那么以后调用的话,直接输入java就可以,免去了输入全路径的麻烦。那么现在开始配置。

我的电脑→属性→高级系统设置→高级→环境变量→系统变量→Path…….我擦,我看到了什么!!!!
image.png

第一行居然有Java相关配置,什么鬼?百度一下,原来这是JDK8安装时自动配置的。这个目录包含了三个exe文件:
image.png

当安装好JDK8时,就可以在cmd中使用java -version来验证是否安装成功,这时调用的是这里面的java.exe。
其它两个不常用。不管了,继续配置环境变量。
Path → 添加路径:C:\Program Files\Java\jdk1.8.0_211\bin
ok,至此环境变量配置好了。

JDK安装时做了什么?

**jdk下bin目录里的java.exe与外部jre中的java.exe的秘密: jdk里的java.exe和jre中的java.exe其实是一样的,但我们在运行的时候优先使用外部jre中的java.exe(即使我们安装了JDK且也配置了环境变量)。

首先,我们看下JDK的安装过程中发生了什么事:
安装JDK时一定会在其子目录下面安装一个JRE,同时,在安装的过程也会询问你是否要安装一个外部的JRE。如果选择安装,就同时拥有了两个jre。这两个JRE本质上没有任何分别。最主要的区别在于:JDK目录里面的JRE是设计用来运行JDK自带的那些工具的(Bin目录下)。而外部的JRE在安装的时候会自动注册到操作系统的path,且文件夹下包含:java.exe javaw.exe javaws.exe 三个文件。因此我们只要安装了外部的JRE(即使JDK没有安装,环境变量没有配置)则运行Java程序时都是用的外部JRE的java.exe程序来运行的(即使安装了JDK且配置了环境变量)(系统的默认path具有优先)。

引用:https://blog.csdn.net/hehainan_86/article/details/38894127

执行java XXX时计算机做了什么?

**java.exe的任务就是在我们电脑上众多的JRE中找到合适的JRE来执行xxx。
java.exe依据以下顺序来寻找JRE:
(1)自己的目录下有没有JRE目录;
(2)父目录下有没有JRE目录;
(3)查询注册表HKEY_LOCAL_MACHINE\Software\JavaSoft\JavaRuntimeEnvironment\
(4)如果都找不到,报错。
所以java.exe的执行结果与我们电脑里哪一个java.exe被执行以及哪套JRE来执行JAVA程序有很大的关系。

另外,java.exe在找到合适的JRE以后,还有一个验证版本的程序,也就是java.exe与JRE的版本一致才可以执行。如果出现版本不一致的问题,首先要确认两件事情:
(1)哪一个java.exe被执行。
(2)java.exe找到哪一套JRE。
只要这两件事情确定了,我们就抓住了问题的来龙去脉,解决起来也就轻而易举了。

JVM在哪?

**
JVM(JAVA Virtual Machine,JAVA虚拟机)是JRE的一部分,JRE是JVM的补充。那么JVM到底在哪里呢?我们打开C:\Program Files\Java\jdk1.8.x\jre\bin,打开server目录,可以找到jvm.dll,这就是我们所说的JVM之所在。

APIs

请仔细观看上面的JDK详情图,其中有一部分展示了Java SE API。开发人员可以使用它们来开发程序。
如果需要查阅某个API,可以去官网查询:https://docs.oracle.com/javase/8/docs/api/

比如说,我需要引用Date And Time API来开发一个获取当前时间的程序。我可以这样写:

  1. import java.time.LocalDateTime;
  2. public class MathTest{
  3. public static void main(String[] args){
  4. LocalDateTime now = LocalDateTime.now();
  5. System.out.print(now);
  6. }
  7. }

首行多了一个import ...; , 这被称为导包。在Java中,如果要使用一个类,必须先通过这种方式,将类的全路径写到import后,置于class声明之上声明。编译执行的结果为:

image.png

那么为什么System类不需要import呢?这是因为Java程序默认引用了java.lang包,所以其下的类都可以直接使用。
而System类就属于java.lang包,java.lang包下的类还包括Math等。

还有一个小问题,为什么java程序的main方法都有一个String[]类型的参数呢?我也不知道,估计是规范如此。
不过,它有什么用呢?我编写了一个测试类,代码如下:

  1. public class TestMain{
  2. public static void main(String[] args){
  3. System.out.print("args's size = :" + args.length);
  4. }
  5. }

image.png

知道了吧,它的作用是接收执行时传入的参数。

API需要持续不断的提高熟悉度。

java程序的运行过程

这里以最简单的Java程序为例,比如说上面的 MathTest 程序。这个程序只有一个Java类:MathTest.class。当我们使用JDK提供的java.exe来运行 MathTest 程序时:MathTest.class首先被从磁盘调入到内存中,之后会有验证、准备、解析、初始化、使用和卸载。这就是类的生命周期。

思考(未验证真实性):
那么类被jvm加载前,操作系统做了什么呢?我们知道启动一个java程序需要使用 java.exe (windows环境),当我们输入java xxxx,并回车后。操作系统首先会为java.exe 开启一个进程,这个进程中的主线程首先会装载JVM,这个过程大致为:

  1. 创建JVM装载环境和配置
  2. 装载JVM.dll
  3. 初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例
  4. 调用JNIEnv实例装载并处理class类

这个装载过程暂且不纠结,它的意思是java.exe程序找到jvm,并将其加载到内存中,然后将需要执行的程序的文件都交给jvm去管理,直到程序执行结束 或者 java.exe的进程结束。

每次执行 java程序,都会将 java.exe 程序的指令加载到内存,这些指令首先把 jvm 指令集加载到内存,并将程序作为参数传给 jvm ,jvm 来管理和执行程序。jvm会装载类,然后接着验证、准备、解析、初始化、使用和卸载类。大概就是这样一个过程。

复杂的Java程序?

古语有云,一而再再而三。其中三表示多个。这里我们以二表示多个。
新建一个有两个类的java程序。并称其为复杂的java程序。
Person类,代码如下:

  1. public class Person{
  2. private String name;
  3. private Integer age;
  4. public Person(String name, Integer age){
  5. this.name = name;
  6. this.age = age;
  7. }
  8. public void setName(String name){
  9. this.name = name;
  10. }
  11. public String getName(){
  12. return name;
  13. }
  14. public void setGender(Integer age){
  15. this.age = age;
  16. }
  17. public Integer getGender(){
  18. return age;
  19. }
  20. }

新建Main类,代码如下:

  1. public class Main{
  2. public static void main(String[] args){
  3. Person person = new Person("jujianfei", 18);
  4. System.out.print(person.getName());
  5. }
  6. }

两个java文件放在同一目录,编译Main.java文件:javac Main.java。因为Main.java中引用了Person.java,所以编译器将Person类也编译成class文件。执行Main程序:java Main,运行结果如下:

image.png

在java程序中,我们可以将不同的功能放到不同的class文件中,然后通过引用来相互使用。我们也可以在一个类中完成所有需要的所有功能,但是这样的形式不利于复用和阅读。因此常用的方式是建多个class来完成一个程序。

package和import?

https://www.cnblogs.com/yqskj/articles/2097836.html
通常,每个java文件中的第一行会有package声明。它后面跟着的是该类的包名。
一个类的全名是由包名+类名组成。如java.util.List,包名是java.util,类名是List。
如果需要使用List类,则需要在java文件的package声明和类声明中间添加导包声明。如:

  1. package cn.org.bjca.entity;
  2. import java.util.List;
  3. public class Test{
  4. List<String> strings = new ArrayList<>();
  5. .......
  6. }

引入包机制是为了解决类名重复问题。

jar文件

在软件领域,JAR文件(Java归档,英语:Java Archive)是一种软件包文件格式,通常用于聚合多个Java类文件、相关的元数据和资源(文本、图片等)文件到一个文件,以便开发Java平台应用软件或库。以ZIP格式构建,以.jar为文件扩展名。用户可以使用JDK自带的jar命令创建或提取JAR文件。
我们熟悉window下的压缩包:.zip文件。jar文件也可以理解为压缩包,不过这个压缩包存储的大多是.class文件。

使用jar.exe将我们上面那个 “复杂的程序”打包:

  1. 新建一个文件夹,将两个class文件放到其中。Main.class放在根目录,Person.class放入子目录entity中。
  2. 新建MANIFEST.MF文件,内容如下:
  1. Manifest-Version: 1.0
  2. Created-By: 1.8.0_211 (Oracle Corporation)
  3. Main-Class: Main
  1. 执行打包命令:jar -cvfm hello.jar MANIFEST.MF Main.class entity\Person.class
  2. 执行jar包:java -jar hello.jar
  3. 至此,打包和执行jar包操作完毕。

jar命令后面的参数意思,可执行:jar 查看帮助。

Java Web

B/S架构和C/S架构?

cs架构举例:QQ。多个客户端可以同时访问一个数据库服务器。客户端程序需要利用客户机的数据处理能力,完成应用程序中绝大多数的业务逻辑和界面展示。
image.png
缺点:

  1. 多人使用,多次安装。
  2. 一次升级,多次安装。
  3. 客户端直接与数据库服务器建立连接,而数据库服务器并发量有限,限制了客户端的同时运行的数量。

bs架构举例:语雀。客户机安装一个浏览器,通过web服务器与数据库进行交互。用户操作的界面是由Web服务器创建的,当要修改系统提供的用户操作界面时,只需要在Web服务器端修改相应的网页文档即可。程序中的业务逻辑处理在Web服务器中完成。浏览器不直接与数据库建立连接,它通过web服务器与数据库建立连接。
image.png

通信协议

在使用bs架构开发程序时,会涉及到浏览器与服务器之间的交互。交互过程见下图:
image.png
大概分三步:

  1. 浏览器向web服务器发出请求。
  2. web服务器处理请求。
  3. web服务器向浏览器返回响应结果。

在整个交互过程中,浏览器使用URL访问服务器,遵循HTTP(或HTTPS)协议传输数据。

URL

Uniform Resource Locator,统一资源定位符。在Web服务器中的每一个网页文件都有一个URL作为访问地址。
在URL中,包含了web服务器的主机名、端口号、资源名以及所使用的的网络协议。如:
http://www.jujianfei.cn:80/index.html

HTTP

浏览器与web服务器之间的数据交互需要准守一些规范,HTTP就是其中一种。
HTTP是由W3C组织推出的,专门用于定义浏览器与web服务器之间交换数据的格式。
浏览器与web服务器之间使用http实现通信的过程见下图:

// TODO 此处应有一个生动的图片

大概分四步:

  1. 建立TCP连接。
  2. 浏览器发出HTTP请求。
  3. web服务器发出HTTP响应。
  4. 关闭TCP连接。

Web资源

放在Intnet上供外界访问的文件或程序称为web资源,根据呈现的效果不同,Web资源可分为动态资源和静态资源。
互联网发展初期,网络上的页面都是由HTML编写的,内容不会发生变化,因此此类资源被称为静态资源,静态资源通常包括:html、css、jpg等。
静态的web资源满足不了所有需求,例如铁路订票网站,每次访问时车票剩余情况会不同,需要动态变化。此类资源被称为动态web资源。动态web资源通常包括jsp、servlet等。

Tomcat

tomcat是sun公司推荐的一款运行servlet和jsp的web服务器。

Web应用

在web服务器上运行的web资源都是以web应用形式呈现的,web应用就是多个web资源的集合。web应用也称为web应用程序或web工程。一个web应用由多个web资源和其他文件组成,其中包括html、css、js、动态web页面、java程序、jar包,配置文件等。开发人员在开发web应用时,应按照一定的目录结构来存放这些文件;否则,在把web应用交给web服务器管理时,不仅可能会使web应用无法访问,还会导致web服务器启动报错。一个web应用的目录结构必须如下图所示。
image.png

tomcat可以同时管理多个web应用,所以在tomcat中可以配置每个web应用的访问地址,两种方式:修改server.xml,在其中添加配置项;在tomcat目录\conf\Catalina\localhost下新建xx.xml。
web应用的web.xml可以配置web应用的默认页。
tomcat有一个管理平台可以控制每个web应用的启动,停止和卸载。

如何新建一个web应用?

  1. 新建一个文件夹,命名为myweb
  2. 新建一个html文件,命名为hello.html,文件内容为:
  1. <html>
  2. <head>
  3. <title>
  4. home
  5. </title>
  6. </head>
  7. <body>
  8. hello web
  9. </body>
  10. </html>
  1. 将myweb文件夹放到tomcat的webapps目录下,启动tomcat,访问:http://localhost:8080/myweb/hello.html
  2. 我们就能看到新建的web资源了,到此为止,第一个web应用已经建立成功了。

    1. ![image.png](https://cdn.nlark.com/yuque/0/2019/png/111066/1571586667907-b01dade9-9258-4df5-bfc0-493dbd913a07.png#align=left&display=inline&height=109&name=image.png&originHeight=109&originWidth=483&size=9361&status=done&width=483)

如果快速建立一个web应用?
**
很显然,类似于京东,淘宝之类的大型网站不可能是通过新建文件夹的方式来开发一个web应用。这样就太低效了。既然web应用的文件位置是固定的,那么我们就可以利用工具来帮助我们建立这个框架,而我们的任务就是为它添砖加瓦。对于Java工程师来说,建立web应用框架的工具主要有 Eclipse 和 IntelliJ IDEA,因为最近常用IDEA作为开发工具,此时就是用IDEA来创建一个web应用。

image.png

  1. File → New → Project → Java,Web Application → Next → 输入名字和路径,完成新建。
  2. 将web目录复制到tomcat下就可以访问了。

image.png

War包

WAR文件(Web应用程序归档,英语:Web application ARchive)是一种JAR文件,其中包含用来分发的JSP、Java Servlet、Java类、XML文件、标签库、静态网页(HTML和相关文件),以及构成Web应用程序的其他资源。

使用IDEA打包:

  1. File → Project Structure → Artifacts → Artifacts → Web Application:Archive → Empty → web(名称)。

image.png

image.png

  1. Build → Build Artifacts → Build → Output directory中就生成了web.war文件了。

image.png

将war文件直接放到 webapps 目录下即可运行。

Servlet

看到了之前写的servlet总结:https://blog.csdn.net/Gnd15732625435/article/details/81275875,拿来用了。
这里也编写一个servlet,来练练手……..
image.png

image.png

image.png

JSP

JSP简介:
https://blog.csdn.net/Gnd15732625435/article/details/81289487
JSP标签库(JSTL):
https://blog.csdn.net/Gnd15732625435/article/details/81434003
JSP-EL:
https://blog.csdn.net/Gnd15732625435/article/details/79164242

JSP开发模型
**
使用JSP技术开发Web应用程序,有两种开发模型可供选择,通常称为JSP Model1 和 JSP Model2。

早期使用JSP开发Java Web应用常见的模式是:浏览器 → JSP → 数据库。强耦合,可读性差,难维护。
为了解决上述问题,Sun公司提供了一种JSP开发的架构模型 JSP Model1:浏览器 → JSP → Java Bean → 数据库。
实现了数据、业务逻辑和页面显示的分离,在一定程序上实现了程序开发的模块化,降低了程序修改和维护的难度。
但是JSP页面仍需要负责流程控制和产生用户界面,对于一个业务流程复杂的大型应用程序来说,在JSP页面中依旧会嵌入大量的Java代码,给项目管理带来很大的麻烦。为了解决这样的问题,Sun公司在Model1的基础上提出了JSP Model2架构模型:JSP + Servlet + JavaBean的技术,此技术将原本JSP页面中的流程控制代码提取出来,封装到Servlet中,从而实现了整个程序页面显示,流程控制和业务逻辑的分离。实际上JSP Model2模型就是MVC设计模式,其中控制器的角色是由Servlet实现,视图的角色是由JSP页面实现,模型的角色由JavaBean实现。
image.png
MVC设计模式

MVC是一种软件设计模式,按功能对软件进行模块划分的方法。将程序分为三个核心模块:模型、视图和控制器。
模型:负责管理应用程序的业务数据以及定义访问控制和修改这些数据的业务规则。
视图:负责与用户进行交互,它从模型中获取数据向用户展示,同时也能将用户请求传递给控制器进行处理。当模型的状态发生改变时,视图会对用户界面进行同步更新,从而保持与模型数据的一致性。
控制器:负责应用程序中处理用户交互的部分,它负责从视图中读取数据,控制用户输入,并向模型发送数据。

Java体系 - 图23

Spring

https://blog.csdn.net/Gnd15732625435/article/details/80991119

未完待续…….
win10默认输入法,表情快捷键:Ctrl + Shift + B 😄😍😋😘👍


参考:https://zh.wikipedia.org/wiki/JDK
https://docs.oracle.com/javase/8/docs/