详细讲解Java开发Web应用程序的控制反转和依赖注入的基本原理,以及容器化编程等概念。在这里我不想重复这些概念的定义,因为那些东西在网上随便百度一下都可以找到。我想通过我的描述把这些概念联系起来,让大家更好的理解他们为什么要这么做。我们每天开发用的框架是什么,它的设计思路和规范的由来。知道它是什么,为什么会这样,可以让我们在开发过程中更好的使用它们,知道问题的大概解决方案。在这篇文章中,我想继续沿用之前的思路,谈谈基于Web的应用需要使用Spring框架容器化管理开发的理解。Web应用与Servlet规范说到应用开发,当然大家都不陌生。现在的应用程序种类繁多,从最初的控制台程序、服务组件程序,到桌面应用程序,再到基于HTTP访问协议的Web应用程序等等。事实上,它们本质上是基于某种输入/输出过程的程序。比如我们最常见的控制台应用,在实际应用中很少用到,就是基于标准I/O实现类的应用,接收命令行作为输入流,控制台作为标准形式的应用输出。它的运行只需要一个进程外壳来构造输入和输出流。至于我们今天要详细讲的Web应用,它其实起源于一个运行在操作系统上的组件程序,只是它们的数据输入输出都是基于网络数据流。网络基础从网络基础知识我们知道,网络上的数据传输需要经过一个7层模型,即从最初的网络硬件抽象定义到最高级的应用层。连接两台物理机,我们需要对两台机器进行识别和命名,这依赖于IP和端口,而网络链路上传输的数据是字节数据流,我们必须知道这些数据流是什么具体格式,但是当我们到达网络层时,我们必须知道它来自哪里,要发送给谁,所以我们需要对其进行一定的格式限制。这种抽象是通过电报格式定义完成的。比如我们需要定义发送的长度,标记为,是否有顺序等等,这些字节流被一个一个的包装成数据包,然后我们就要定义各个发送端和接收端之间的协议,也就是告诉对方我发送了什么,你是怎么接收的,比如一个完整的数据包有多长,数据包的顺序等等,这些都是在我们知道了双方的IP地址之后通信存储和如何连接,也就是我们所说的传输基于控制协议TCP,我们定义了更高级的应用协议,如HTTP、FILE、MAIL等协议。当然,最常见的协议是HTTP协议。HTTP协议是基于基本消息格式定义的更高层次的抽象。它可以告诉通信双方如何解析我们通信的数据。以超文本传输??协议为例,它规定了头部信息和内容信息,还规定了处理这些信息的方法和结果反馈码,也就是我们常说的GET、POST、DELETE、OPTIONS等,returncode比如从100到500系列,当然这些都进入了应用协议部分。我们所有的Web应用程序都是基于点对点通信的应用程序。也就是说,要创建这样一个程序,首先要确定两个可以连接的点,首先是主机名或者IP地址,然后是我们要连接的具体应用,一般会体现在哪个端口或路径上端口下方的哪个端口。有了peer的定义和描述,我们就可以定义其控制传输的抽象,socket概念。编解码器问题的本质是为输入和输出流创建通道。网络数据流是通过Socket的概念来定义和描述的。对于我们的编程,尤其是Java编程,我们只需要在我们应用程序管理的空间中定义一个可以连接到网络套接字的通道,同时在内存中绘制一个缓冲区,让通道有可操作的空间即可。然后利用数据在不同缓冲区之间流动的过程,对数据进行相应的更改。比如最基本的就是如何将网络传输的字节流转化为我们高级语言定义高级数据类型的过程。这个过程通常称为解码,同样当我们需要将应用程序可以理解的各种数据类型转换成可以通过网络传输到其他地方的字节流时,这个过程称为编码。因为目前硬件能够理解的状态只有两种,而这两种状态用数字表示为二进制0和1,所以在我们使用的很多高级编程语言中,需要转换成哪些复杂的数据类型二进制字节形式只有这样才能被CPU理解并被网络硬件传输。因此,我们的编程不可避免地需要完成这个编码和解码的过程。当然,随着高级语言的不断演进,各种常用的处理已经转化为各种语言标准的类库或函数包,我们只需要使用即可。除非要自己写通信协议或者定义特殊的数据格式,一般不会涉及到codec。了解了所有的应用都是基于对数据流的处理之后,再来看Web应用,Web应用是基于网络服务和独立访问结构的应用,也就是我们常说的Server-Client模式。关于Servlet,这里之所以定义server和client,主要是功能上的区分,但底层本质上是两台计算机之间的连接,通过字节流交换数据,通过协议指定传输控制和数据解码,而我们的web应用程序是基于HTTP协议的网络应用程序。因为涉及到网络处理,技术人员把相关的网络处理部分分离出来,规定了很多规范,比如端点描述规范、数据传输格式规范、如何使用所在的计算机等。操作系统环境的设置等规范,体现在Java编程中就是我们都熟悉的Servlet规范。该规范首先告诉我们,基于Web的应用程序的基本网络部分需要在每台联网计算机上都有作用。我们称这个角色为容器,或网络服务器。就是实现计算机网络的识别和连接,指定解析数据格式等工作,当然后来我们把它开发成一个综合的服务器,在处理HTTP协议的同时,还可以通过一些接口进行交互调用和操作系统系统的功能组件。如网卡、文件输入输出控制器等。我们可以简单描述一下Servlet容器的实现功能。首先,它需要对自己运行的主机信息有一个抽象,让运行的程序能够理解它,使用它能用到的资源。然后,需要将基于网络的字节流转换为高级语言数据类型,比如将字节流解析为遵循HTTP协议的数据格式,HttpRequest、HttpResponse、HttpServletRequest、HttpServletResponse等。同时,将宿主服务器的环境参数抽象出来,引入到容器中与我们的应用进行交互。所以只要实现了Servlet规范,就可以作为操作系统和我们应用程序之间的媒介。Servlet容器市场上有很多成熟的Servlet容器产品,如Tomcat、Jetty、Weblogic、Glassfish等。有很多轻量级的,它只负责将输入的网络数据流转换成我们的应用程序可以理解和处理的数据形式,而这个过程是通过创建输入输出数据流的过程来完成的。一些商业应用的实现有更多的附加内容,比如系统环境资源的抽象继承,比如数据库连接资源、文件输入输出组件等。我们开发的应用程序是基于我们的设计和开发原则。我们首先将应用程序分解为功能组件,将每个功能组件设计成一个可以在容器中独立运行的组件。该组件是HttpServlet请求处理组件。我们会根据请求的目标地址来标记各种功能,然后使用这些唯一的目标地址和HTTP方法来识别运行的目标组件,而这个组件可以通过容器与计算机环境进行交互。所以,Servlet的顶层抽象是一个服务方法,这个方法的入参是容器封装的请求体、应答体和环境变量对象。当然我们会根据HTTP协议细化支持的HTTP方法,所以我们可以使用doGet、doPost等方法来完成具体的处理。通过我们对这样一个基本规范的功能实现,我们就有了一个可以容纳和管理特定功能应用程序组件的容器。这个容器就是我们所说的网络服务器。如果你明白Servlet规范的本质是网络数据流的封装和编解码,那么你就可以从基本的二进制数据流的封装和编解码入手,自己设计自己的Web应用服务器。即实现点对点的通信处理。在这里,当前微服务架构的基础是web服务器的基础网络实现的再分解设计。Servlet3.0引入了反应流的概念,即通过receivercontrol来管理大批量数据流的输入输出。Spring框架与Web应用设计了解了上述Web应用的结构之后,我们再来看看Spring框架在Web应用开发中的作用。我们知道在Java企业级开发中有一个JavaEE框架,它其实是基于Servlet容器的。它只是组件了企业级应用开发的所有基本功能,如容器化依赖注入、JPA等。当然,还必须有与之配套的Web应用服务器来支持它的运行。同一个Spring框架的核心部分是组件容器,它的作用是通过更加有效和轻量级的方式组织和管理应用程序的各种功能组件。巧妙之处在于将整个组件设计为一个Servlet组件实现,是Spring框架中的核心DispatchServlet。和所有的Servlet定义规范一样,我们需要用一个请求的目标路径来标识Servlet,然后让Servlet容器在启动时加载它并绑定到目标路径,从而在请求的处理器中启动一个应用组件管理容器根目录,并将其处理器处理程序实现为前端控制模式,负责识别匹配其根目录后的URL部分,从而实现Spring容器中负责处理后续URL资源的处理器的路由。简单来说,当一个外部访问请求通过网络到达Web服务器时,会根据Servlet规范和HTTP协议,解码成HttpServlet请求和应答数据结构类型,然后得到访问的目标资源的URL通过它会被解析为匹配我们注册在Spring容器中用来处理它的组件和方法名来完成Servlet请求的处理。由于我们在开发应用的时候,除了不断的文件上传下载处理外,大部分都是将二进制数据转换成JSON数据格式或者XML格式,所以我们只需要在Spring容器中注册相应的处理组件即可。小结说到这里想说的话还没说完,不过文章的篇幅已经超出预期,就此打住吧,只能在另一篇文章中继续说了。本文简要介绍了Web应用的特点和能够辅助Web应用运行的基本容器服务规范,进而到Spring框架的设计原则和结构实现设计。在这里我希望带大家从Web应用区别于其他类型应用的特点,到支持Web应用运行的Servlet规范的实现,再到Spring框架在Web应用中所扮演的角色。.接下来我会继续沿着这个思路,讲讲MVC模式和反应式流处理模式。
