SpringBoot进阶1:Java Web开发简介和痛点

1 引导语

该专栏主要是讲解使用 SpringBoot 框架开发 Java 企业级 Web 应用的相关用法和原理,所以在进入 SpringBoot 框架的讲解之前,首先介绍一下 Java web 开发的相关原理,以便读者在之后能更好地理解基于 SpringBoot 开发 Java 企业级 Web 应用的相关用法和原理。

2 基于 Servlet 组件的 Java Web 应用开发

2.1 企业现状

Java 语言是目前最流行的企业级 Web 应用开发语言之一,在企业级 Web 应用开发当中,虽然 Java 也提供了JSP 技术来开发网页页面,但是目前的企业级 Web 应用一般都是采用前后端分离架构,所以 Java 语言主要用于开发服务端 Web Restful API 接口来供浏览器、安卓、IOS 等客户端调用

2.2 Java 语言的 Web 通信实现: Servlet

​ 在 Java Web 应用的运行过程当中,客户端与服务端之间是基于 HTTP 协议来进行通信的,Java 语言提供了 Servlet 组件来处理 HTTP 协议相关的底层细节,以及定义了处理 HTTP 请求的方法模板来供应用程序自定义业务处理逻辑,即接收客户端的 HTTP 请求,然后由应用程序自定义请求的业务处理逻辑,最后产生对应的 HTTP 响应返回给客户端。一个 Web 请求与响应的具体流程如图所示:

SpringBoot进阶1:Java Web开发简介和痛点

​ 下面我们一起来学习下基于 Servlet 组件开发 Java Web 应用的核心实现流程:

  1. 自定义 Servlet 实现:在自定义 Servlet 的实现时,一般是通过继承 HttpServlet 并根据业务逻辑来重写其提供的对应HTTP 协议相关请求类型的处理方法,如 GET 请求,POST 请求等,分别为 doGet,doPost 方法等,不能根据业务特点来自定义其他名字的方法,HelloWorldServlet 的实现如下:

public class HelloWorldServlet extends HttpServlet { /** * HTTP GET请求处理 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 自定义请求的业务处理逻辑 } /** * HTTP POST请求处理 */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 自定义请求的业务处理逻辑 }}

  1. 配置 URI 映射:在 Servlet 规范当中,需要在应用配置文件 web.xml 中为每个 Servlet 组件配置一个映射 URI,如下是在 web.xml 文件中配置 HelloWorldServlet 和 HelloWorldServlet 对应的 URI 映射,其中映射的 URI 为 “/servlet/helloworld”。所以如果应用存在多个 Servlet 实现,则需要在 web.xml 文件中配置每个 Servlet 和其对应的 URI 映射,

tips:由于每个 Servlet 都需要这样配置,所以如果存在大量 Servlet,则既会增加工作量,又非常容易配置错误,如路径 URI 拼写错误导致无法访问。

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- Servlet配置 --> <servlet> <!-- 该Servlet的名字,可以任意 --> <servlet-name>HelloWorldServlet</servlet-name> <!-- 该Servlet类的全限定名 --> <servlet-class>com.xyz.demo.HelloWorldServlet</servlet-class> </servlet> <!-- Servlet映射配置 --> <servlet-mapping> <!-- 需要和以上的Servlet的名字相同 --> <servlet-name>HelloWorldServlet</servlet-name> <!-- 浏览器访问该URL时,请求会被该Servlet处理 --> <url-pattern>/servlet/helloworld</url-pattern> </servlet-mapping></web-app>

  1. 打包部署:最后需要将这些 Servlet 组件编译打包到一个 war 包,然后将该 war 包部署到 Servlet 容器 Tomcat 中。后续的客户端请求都是发送给 Tomcat ,然后由 Tomcat 根据请求的 URL 来判断需要是哪个应用的请求和请求哪个 URI 路径, 最后转发给对应的 Servlet 组件处理。

知识拓展:Tomcat 是基于 Servlet 规范实现的 Servlet 容器,顾名思义,可以存放多个 Servlet 组件,故 Tomcat 中可以部署多个 Java Web 应用,每个应用由多个 Servlet 组件组成。

3 基于Servlet开发的痛点分析

​ 基于 Servlet 开发 Java Web 应用是比较原始的开发方式,目前 Java 企业级应用一般很少直接使用这种方式,而是使用更高级的 Java Web 开发框架,如 Struts,SpringMVC 等,这些框架在内部封装了 Servlet 的相关细节,使得应用开发者只需要专注于业务开发即可。通过以上关于 Servlet 的介绍,我们可以总结出基于 Servlet 这种底层组件来开发 Java Web 应用存在以下痛点:

3.1 存在耦合

​ 由以上 HelloWorldServlet 的定义可知,通过继承 HttpServlet 类,然后重写 HttpServlet 类根据 HTTP 请求类型定义的 doGet,doPost 等方法来实现业务逻辑的处理。这样就会导致应用业务逻辑与 Java 语言自身功能组件,即 Servlet 组件,存在耦合,不利于应用的拓展。

​ 由于 Servlet 是以 HTTP 协议的请求类型维度来定义方法的,如果是业务逻辑复杂、存在大量 URL 的 Java Web 应用,则需要开发大量的 Servlet 类,不能做到在一个Servlet 类中定义多个不同 URL 的处理方法。

3.2 手动配置太多、可维护性差

​ 需要在应用配置文件 web.xml 中配置每个 Servlet 和该 Servlet 的 URI 映射,所以如果应用存在大量的Servlet,则需要在 web.xml 中配置大量的 Servlet 和该 Servlet 的 URI 映射,使得 web.xml 文件内容太多,应用开发者维护难度大且容易配置出错,影响应用的可维护性;

3.3 部署困难

​ 在部署层面,需要将 Java Web 应用打包为 war 包,然后部署到 Servlet 容器 Tomcat,故应用是运行在 Tomcat 进程的。同时由于可以在 Tomcat 部署多个 Java Web 应用,所以不能为每个应用都自定义相关的运行时参数,如配置 JVM 参数等来针对某个应用进行调优。

​ 虽然可以通过在每个 Tomcat 进程只部署一个 Java Web 应用来实现,但是这种方式需要在服务器部署多个 Tomcat 进程或者每个服务器都需要部署一个 Tomcat 进程,额外增加了运维的工作量和服务器资源开销,特别是在微服务架构非常流行的今天,一个大型系统可能由成百上千个服务组成,如果基于这种方式部署,则对运维来说简直就是噩梦。

4 基于SpringMVC开发Java web应用

​ 以上介绍了基于 Servlet 开发 Java Web 应用的相关用法和痛点,其中一个就是由于 Servlet 组件提供的相关方法太过底层,导致存在应用业务逻辑与 Java 语言自身功能组件的耦合,另外就是需要在 web.xml 中配置每个 Servlet和该 Servlet 对应的 URI 的映射,所以不利于应用的拓展和维护。所以为了解决这个问题,Spring 开发团队提供了 SpringMVC 框架。

SpringMVC 框架的核心设计主要包括三部分:

  1. 使用一个统一的 DispatchServlet 来接收应用的所有请求 ,只需要在应用配置文件 web.xml 中配置该DispatchServlet 和其 URI 映射即可,其中 DispatchServlet 是使用模糊匹配 “/*” 来拦截针对该应用的所有请求。
  2. 在 SpringMVC 框架内部定义了 MVC 模型的实现,即请求处理控制器 Controller,视图 View,数据模型 Model。其中业务请求处理方法和对应的 URI 的映射是在请求处理控制器 Controller 定义的,方法是从业务的角度,而不是 HTTP 请求类型的角度来定义的,故可以在一个 Controller 定义多个请求处理方法来处理不同的业务请求,在每个方法中使用 @RequestMapping 注解来定义对应的 URI 映射,且每个方法可以根据业务含义来命名,从而增加了应用代码的可读性和可维护性。
  3. 相对于基于 Servlet 开发 Java Web 需要定义大量 Servlet 类,SpringMVC 框架减少了应用中需要维护的类的数量,降低了开发难度,以及降低了业务与 Java 语言自身功能组件的耦合。

知识拓展:

不过由于 SpringMVC 框架是依赖于 Spring IOC 容器来对 Controller 等 Java bean 对象进行管理,所以需要在应用中维护 Spring 容器的配置文件applicationContext.xml

SpringMVC 自身也存在配置文件 dispatcher-servlet.xml(名字可以自定义,具体可以查看 Spring 和 SpringMVC 的相关官方文档)。

最后还需要在应用配置文件 web.xml 中配置 SpringMVC 框架的请求分发器 DispatchServlet 和其 URI 映射。

以上列举了需要进行配置的三种配置文件,所以我们基于 SpringMVC 框架来开发 Java Web 应用也同样存在配置繁琐的问题。具体怎么样做才最简便,后面我们会讲到,一起来期待吧

^ ^。

5 基于SpringMVC的痛点剖析

5.1 维护性差

​ 虽然 SpringMVC 框架解决了 Servlet 的方法太过底层,导致业务代码与 Java 自身功能组件代码存在耦合的问题,以及减少了应用中 Servlet 组件和在 web.xml 配置 URI 映射的数量。但是 SpringMVC 框架自身又引入了配置文件,如 Spring IOC 容器的配置文件 applicationContext.xml,SpringMVC 的配置文件 dispatcher-servlet.xml,或者基于注解和 Java 类的应用配置等。

​ 由于可选的配置方式太多,导致不同应用开发人员可能会根据自身喜好选择其中一种配置方式,所以在项目的开发迭代过程中,项目会变得越来越难以维护,这样进一步增加了应用的开发和维护难度。

5.2 兼容性不好

​ 除此之外,企业级 web 应用一般需要访问数据库,使用缓存等。所以需要依赖一系列其他第三方框架的功能 jar包,如基于 maven 进行 jar 包管理时,由于每个功能 jar 包都可能存在多个版本,故需要在 maven 包管理文件 pom.xml 中为每个功能 jar 包指定当前应用所使用的版本,并且可能会出现不同功能 jar 包的版本不兼容、类冲突等问题,从而导致程序启动失败。

​ 所以应用开发人员需要额外测试和维护各个 jar 包版本的兼容关系,这也增加了 Java Web 应用的开发难度和复杂度。

5.3 部署困难

​ 最后是基于 SpringMVC 进行 Java Web 应用开发也是需要将项目打包为 war 包,然后部署到 Tomcat,在Tomcat 进程运行该应用,所以没有从根本上解决 Java Web 应用对 Servlet 容器 Tomcat 的依赖,即还需要在服务器额外部署一个 Tomcat 进程来运行该应用,所以应用的相关运行参数,如 JVM 参数等,还是需要通过对Tomcat 进程来进行配置,而不能直接每个应用进行配置,以及也存在运维难度大等问题。

6 总结

​ 我们今天讲了使用 Servlet 和 SpringMVC 这两种方式进行 Java Web 应用开发时,都存在需要在配置文件中进行大量配置的问题,并且随着应用越来越复杂,配置量也会越来越多,从而影响应用的拓展性,增加应用的开发和维护难度。

​ 在部署的时候,应用都需要依赖于额外运行的 Tomcat 进程来运行,这种部署方式不能根据应用自身特点来指定应用的运行时参数,如 JVM 参数,还需要在服务器额外部署 Tomcat 进程,增加服务器的资源开销和运维工作量。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2023年4月25日 上午8:05
下一篇 2023年4月25日 上午8:15

相关推荐