JavaWeb编年史(黄金时代)1

简介: 从JavaWeb编年史的远古时代,一直到白银时代,我们见证了JavaWeb开发模式的大致变迁。说白了,就是不断解耦合的过程。接下来我们来聊聊项目架构的演变,之所以我把它划到了JavaWeb编年史(黄金时代),是因为在早期的JavaWeb项目中,很少有架构的概念,基本就是一个单体项目,然后不断在已有项目上堆砌新的功能。所以,当我们开始有了架构的概念,其实也是一种非常大的进步,我个人称之为黄金时代,哈哈。

从JavaWeb编年史的远古时代,一直到白银时代,我们见证了JavaWeb开发模式的大致变迁。说白了,就是不断解耦合的过程。接下来我们来聊聊项目架构的演变,之所以我把它划到了JavaWeb编年史(黄金时代),是因为在早期的JavaWeb项目中,很少有架构的概念,基本就是一个单体项目,然后不断在已有项目上堆砌新的功能。所以,当我们开始有了架构的概念,其实也是一种非常大的进步,我个人称之为黄金时代,哈哈。


对于小公司来说,大部分项目都比较小,交给一个人开发足以,使用单体项目也无所谓。但是,随着互联网的发展,项目的功能越来越多,就得考虑把项目进行拆分,从而进一步解耦。


JavaWeb编年史 - 黄金时代,就是架构不断升级的年代,各种新的思想层出不穷,但是目的只有一个:拆分项目,进一步解耦。(其实也并没有特别严谨的时间顺序啦,如此行文只是为了统一下文章风格哈)


模块化时代


在解释模块化之前,我们先回顾一下,面向对象的三大特性是什么?


哦,聪明的你肯定立刻就想到继承、封装和多态。面向对象使得Java代码能够轻易被复用,Java程序变得更加灵活。


现在,我们把宾语换成Java项目,就变成了:面向对象使得Java项目能够轻易被复用,Java程序变得更加灵活。


是啊,如果受体变成项目,项目之间也去实现继承,那么很多功能就可以得到复用。而maven可以通过聚合工程,来实现这一点,这个功能是maven本来就具备的。那么,只要我们是用maven来搭建项目,就可以实现真正的模块化开发。


回想一下上一节的springboot项目,结构是这样的:


a9d08ac5c475c3a1bf3c1089f65815a2.png


项目根据package来进行模块划分,看似没有问题,但是非常不好维护。


主要体现在:


1.如果其他项目有类似的功能,则需要每一个项目都写重复的代码,比如xxxService、xxxDao等。


2.团队协作的时候,不管你是用SVN还是git,都有极大概率多人操作同一个类,不利于版本管理。


3.项目如果体量越来越大,则文件会越来越多,整体会变得臃肿。


因此,需要用模块化的方法将这些package分化,简单来说就是把一个个package变成一个个module。


moudle叫做组件,或者叫子工程、子项目都可以。


2.演示将单体项目模块化

刚才那张图,我们需要将每一个package拆出来,做成一个module,最终项目结构就变成了这样:

f20e8ee8de7904b1a2b419b0cade5ec8.png

下面我们依次来介绍各个模块的作用。

web-api

这个是接口模块,主要是提供服务给外界,对应于之前的controller层

1b36ba7f5578254b9c5a9835ed9a316e.png

因为是前后端一体的项目,这边继续保留webapp。如果做的是前后端分离项目,则不需要webapp。

注意,启动配置这边要填写这个,否则访问不了JSP页面。

7950e3c89b8cd81dc50b19029ea709b9.png

然后webapp的目录要进行如下配置,否则也是访问不了页面的。

2d44b3db348ea83315ab3bae0414ec92.png


web-api是整个工程的门面。

pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>web1</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>web-api</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>web-model</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>web-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

从pom中可以看到,web-api需要依赖web-service,web-model。

web-service

这是服务模块,为web-api提供服务支持,对应原来的service。

0af3bfdfa73ed880ec2d82bd69a43016.png

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>web1</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>web-service</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>web-model</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>web-dao</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

从pom中可以看到,web-service需要依赖web-dao,web-model。

web-dao

这是数据访问模块,对应原来的dao。

bd7b5cd96705726f80f3ef4c7737a8ff.png


pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>web1</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>web-dao</artifactId>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>web-model</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

从pom中可以看到,web-dao需要依赖web-model。

web-common

这是公共模块,主要放置一些工具包和类库,因为项目只是演示,所以目前这是一个空模块。

父项目

父项目就是这个web7,其余5个模块都是在这个项目里面的。


1aa6ea34517a3c014c3c3cf9a1d5ed5f.png

体现在pom文件,就是

<modules>
  <module>web-common</module>
  <module>web-api</module>
  <module>web-dao</module>
  <module>web-model</module>
  <module>web-service</module>
</modules>

然后每一个模块的pom中都有一个parent

<parent>
    <artifactId>web1</artifactId>
    <groupId>org.example</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

也就是说,那5个模块都是父项目的子项目,继承自父项目。

打包方式:

<packaging>pom</packaging>

还有,顶层的父项目的打包方式必须为pom,表明这是一个聚合工程。pom工程就像是一个公共类,给下面的子模块提供了maven依赖版本号,方便控制版本。其实也没有什么特别神秘的地方。


模块化的好处

我们一般所说的模块化,就是指的maven聚合项目。


聚合的意义

对于一个大型的项目,如果我们直接作为一个工程开发,由于相互之间的依赖我们只能从头到尾由一组人开发,否则就会出现一个类好多人开发,相互更改的混乱局面,这个时候我们就将项目进行了横向和纵向的拆分。


所谓的横向的拆分就是我们平常说的三层架构,将项目分成了web层,service层、dao层(web层也被叫做表现层,service层也被叫做业务层,dao层也被持久层),可以理解为将一个功能模块的不同调用过程进行了水平方向的拆分。


所谓的纵向拆分就是将一个项目的多个功能模块进行了,可以理解为为了完成一个系统,深度(纵向)分析需要有哪些功能,然后将这些功能独立出来,进行了(纵向)拆分。


横向拆分后,每个功能模块进行了单独的开发之后,项目整合的时候就需要有一个能够整合这些项目或者模块的工程,这就是所谓聚合工程的意义。


相关文章
|
3月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
459 37
|
2月前
|
前端开发 Java 应用服务中间件
Javaweb学习
【10月更文挑战第1天】Javaweb学习
33 2
|
2月前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
66 5
|
3月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
3月前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
120 2
|
3月前
|
SQL JSON JavaScript
JavaWeb基础9——VUE,Element&整合Javaweb的商品管理系统
Vue 指令、生命周期、this和$、vue脚手架进行模块化开发/ElementUI框架、综合案例,element商品列表展示增删改查
JavaWeb基础9——VUE,Element&整合Javaweb的商品管理系统
|
5月前
|
存储 程序员
JavaWeb之Listener监听器
JavaWeb之Listener监听器
89 0
|
20天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
11天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
6天前
|
监控 Java 开发者
深入理解Java中的线程池实现原理及其性能优化####
本文旨在揭示Java中线程池的核心工作机制,通过剖析其背后的设计思想与实现细节,为读者提供一份详尽的线程池性能优化指南。不同于传统的技术教程,本文将采用一种互动式探索的方式,带领大家从理论到实践,逐步揭开线程池高效管理线程资源的奥秘。无论你是Java并发编程的初学者,还是寻求性能调优技巧的资深开发者,都能在本文中找到有价值的内容。 ####