搞懂 JavaEE 分層模型,這篇就夠了!Web 服務(wù)器 + 核心框架 + 交互邏輯全解析
1.1 JavaEE應(yīng)用的分層模型
- 表現(xiàn)層:也就是常說的WEB層。主要負(fù)責(zé)接收客戶端請(qǐng)求,向客戶端響應(yīng)結(jié)果。表現(xiàn)層也細(xì)分為:展示層和控制層。
 
展示層:負(fù)責(zé)展示結(jié)果。由一系列JQuery、Angular、Vue等各種前端框架組成。
控制層:負(fù)責(zé)接收請(qǐng)求和攔截非法請(qǐng)求。由一系列JSP頁面、FreeMarker頁面組成。
- 業(yè)務(wù)層:由一系列業(yè)務(wù)邏輯對(duì)象組成,這些業(yè)務(wù)邏輯對(duì)象實(shí)現(xiàn)了Domain Object方法及其他組件實(shí)現(xiàn)的業(yè)務(wù)邏輯方法。
 
Domain Object(領(lǐng)域?qū)ο?:此層由一系列POJO對(duì)象組成,用于實(shí)現(xiàn)業(yè)務(wù)邏輯方法。
事務(wù)控制:業(yè)務(wù)層經(jīng)常需要確保事務(wù)的一致性。
- 持久層:主要負(fù)責(zé)數(shù)據(jù)的持久化,數(shù)據(jù)層通常包括數(shù)據(jù)庫和數(shù)據(jù)訪問層。
 
數(shù)據(jù)庫:指具體的數(shù)據(jù)庫軟件,例如mysql、Oracle等。通常是利用數(shù)據(jù)庫驅(qū)動(dòng)以及數(shù)據(jù)庫連接池技術(shù)實(shí)現(xiàn)與數(shù)據(jù)庫的連接最原始的當(dāng)然就是JDBC,后續(xù)衍生出來的JPA、Mybatis以及Mybatis-plus都是對(duì)于JDBC的封裝,簡(jiǎn)化開發(fā)。
數(shù)據(jù)訪問層:也就是DAO(Data Access Object),用于編寫持久層接口,用于將實(shí)體對(duì)象轉(zhuǎn)換為業(yè)務(wù)對(duì)象。
圖片
交互邏輯:
表現(xiàn)層交由用戶進(jìn)行控制,用戶操作表現(xiàn)層,將請(qǐng)求發(fā)送至控制層
控制層調(diào)用業(yè)務(wù)層,處理用戶請(qǐng)求
業(yè)務(wù)層根據(jù)業(yè)務(wù)的實(shí)際需求,調(diào)用持久層將用戶操作存儲(chǔ)在數(shù)據(jù)庫,或從數(shù)據(jù)庫取出數(shù)據(jù)
持久層返回操作結(jié)果給業(yè)務(wù)層
業(yè)務(wù)層返回持久層結(jié)果給控制層
控制層進(jìn)行一定的數(shù)據(jù)封裝、渲染,返回給表現(xiàn)層
1.2 表現(xiàn)層
表現(xiàn)層主要需要解決的問題是展示層和控制層的如何通信。
- 展示層不管是采用JSP還是VUE,都需要將用戶的請(qǐng)求發(fā)送到控制層。
 - 控制層不管是用Java,還是Python,也都需要將響應(yīng)結(jié)果反饋給展示層。
 
1.2.1 Web服務(wù)器
Web服務(wù)器:Web服務(wù)器提供了各式各樣的功能,側(cè)重點(diǎn)也不也一樣,Java中常用的三種Web服務(wù)器就是Tomcat、Undertow、Jetty
1)Tomcat
Tomcat 是 Apache 軟件基金會(huì)開發(fā)的開源 Web 服務(wù)器,也是 Java Web 應(yīng)用中最廣泛使用的 Servlet 容器之一。它支持 Java Servlet 和 JavaServer Pages (JSP) 技術(shù),適用于傳統(tǒng) Java Web 應(yīng)用的開發(fā)和部署。Tomcat 以其穩(wěn)定性和社區(qū)支持而聞名,適合中小規(guī)模企業(yè)級(jí)應(yīng)用 。
Tomcat 的主要特點(diǎn)包括:
- 穩(wěn)定性高:經(jīng)過長期發(fā)展和廣泛使用,Tomcat 在穩(wěn)定性和可靠性方面表現(xiàn)優(yōu)異。
 - 支持標(biāo)準(zhǔn) Java Web 技術(shù)棧:支持 Servlet、JSP、JSTL 等標(biāo)準(zhǔn)技術(shù)。
 - 社區(qū)支持廣泛:擁有龐大的用戶社區(qū)和豐富的文檔資源。
 
2)Jetty
Jetty 是一個(gè)輕量級(jí)、高性能的 Java Web 容器,由 Eclipse 基金會(huì)維護(hù)。它支持 Servlet 3.1 和 WebSocket,適用于高性能和分布式系統(tǒng)。Jetty 以其輕量級(jí)和快速啟動(dòng)的特點(diǎn)而受到青睞,適合嵌入式應(yīng)用和微服務(wù)架構(gòu) 。
Jetty 的主要特點(diǎn)包括:
- 輕量級(jí):?jiǎn)?dòng)快、內(nèi)存占用低,適合嵌入式應(yīng)用和微服務(wù)。
 - 高性能:支持異步非阻塞 I/O,適合高并發(fā)場(chǎng)景。
 - 靈活性:支持按需加載組件,便于擴(kuò)展和定制。
 
3)Undertow
Undertow 是 Red Hat 開發(fā)的高性能 Web 服務(wù)器,基于 NIO 實(shí)現(xiàn),支持異步非阻塞 I/O 和 HTTP/2。它被廣泛用于 WildFly 應(yīng)用服務(wù)器,并且在 Spring Boot 中作為可選的內(nèi)嵌服務(wù)器。Undertow 以其高性能和靈活性而受到關(guān)注 。
Undertow 的主要特點(diǎn)包括:
- 高性能:在高負(fù)載下表現(xiàn)優(yōu)異,吞吐量高,適合高并發(fā)場(chǎng)景。
 - 靈活性:支持異步非阻塞 I/O,適合實(shí)時(shí)通信和微服務(wù)架構(gòu)。
 - 輕量級(jí):配置簡(jiǎn)單,易于集成到 Spring Boot 等框架中。
 
總結(jié)
- Tomcat:適合傳統(tǒng) Java Web 應(yīng)用,穩(wěn)定可靠,社區(qū)支持廣泛。
 - Jetty:適合輕量級(jí)、高性能和嵌入式應(yīng)用,啟動(dòng)快、內(nèi)存占用低。
 - Undertow:適合高性能、高并發(fā)場(chǎng)景,支持異步非阻塞 I/O,適合微服務(wù)和實(shí)時(shí)通信。
 
其他服務(wù)器
- Jboss:是一個(gè)遵從了javaEE規(guī)范的、開源的、純EJB服務(wù)器,它支持所有的javaEE規(guī)范
 - GlassFish:由Oracle公司開發(fā)的一款JavaWeb服務(wù)器,是一款強(qiáng)健的商業(yè)服務(wù)器,達(dá)到產(chǎn)品級(jí)質(zhì)量
 - Resin:自身采用Java開發(fā),是目前最快的JSP、Servlet運(yùn)行平臺(tái),支持EJB,商用收費(fèi),個(gè)人免費(fèi)
 - WebLogic:是Oracle公司的產(chǎn)品,目前應(yīng)用最廣泛的Web服務(wù)器,支持JavaEE規(guī)范,適合大型項(xiàng)目(收費(fèi),大公司用得比較多)
 - Nginx服務(wù)器:負(fù)載均衡服務(wù)器,主要用于反向代理,詳細(xì)介紹參考:Nginx
 - IIS(Internet Information Services)服務(wù)器:微軟公司開發(fā)的WEB服務(wù)器,允許托管網(wǎng)站和Web應(yīng)用,并提供了一系列用于Web服務(wù)器管理的功能
 
1.2.2 JSP、Servlet、JavaBean
JSP是動(dòng)態(tài)Web,HTML是靜態(tài)Web。
JSP和Servlet底層實(shí)現(xiàn)原理一致,**JSP必須被Web服務(wù)器編譯為Servlet**,才能使用,所以真正在Web服務(wù)器中運(yùn)行的是Servlet。
JavaBean是用于數(shù)據(jù)傳輸?shù)?,?qǐng)求/響應(yīng)攜帶的數(shù)據(jù)。
Tomcat版本  | Servlet/JSP版本  | JavaEE版本  | 運(yùn)行環(huán)境  | 
4.1  | 2.3/1.2  | 1.3  | JDK1.3  | 
5.0  | 2.4/2.0  | 1.4  | JDK1.4  | 
5.5/6.0  | 2.5/2.1  | 5.0  | JDK5.0  | 
7.0  | 3.0/2.2  | 6.0  | JDK6.0  | 
8.0  | 3.1/2.3  | 7.0  | JDK7.0  | 
Servlet在2.5版本及之前都是采用的xml配置的方式,在3.0之后就是注解的方式實(shí)現(xiàn)了 Servlet在4.x中提供了異步請(qǐng)求、注解、增強(qiáng)的Servlet API、非阻塞IO。
1.2.3 靜態(tài)web和動(dòng)態(tài)web
1.2.3.1 靜態(tài)web
html\htm網(wǎng)頁,通過直接獲取的方式,進(jìn)行頁面展示,所有的用戶看到的都是同一個(gè)頁面 css、js、txt mp4 jpg等都算是靜態(tài)web資源。
圖片
靜態(tài)web存在的缺點(diǎn):
- Web頁面無法動(dòng)態(tài)更新,所有用戶看到的都是同一個(gè)頁面。
 - 無法和數(shù)據(jù)庫交互(數(shù)據(jù)無法持久化,用戶無法交互)。
 
1.2.3.2 動(dòng)態(tài)web
jsp/sevlet動(dòng)態(tài)資源,可以與數(shù)據(jù)庫進(jìn)行交互,實(shí)現(xiàn)動(dòng)態(tài)頁面:
ASP:微軟的產(chǎn)品,底層是在HTML中嵌入VB的腳本,ASP+COM,導(dǎo)致在頁面中包含太多業(yè)務(wù)邏輯代碼。
PHP:開發(fā)速度很快,功能很強(qiáng)大,跨平臺(tái),代碼很簡(jiǎn)單,但是無法承載大訪問量的情況。
JSP:本質(zhì)是Servlet,是sun公司開發(fā)的B/S架構(gòu),可以承載三高(高性能、高可用、高并發(fā))問題,語法像ASP。
圖片
動(dòng)態(tài)Web的缺點(diǎn):假如服務(wù)器的動(dòng)態(tài)web資源出現(xiàn)錯(cuò)誤,我們需要重新編譯后臺(tái)程序,重新發(fā)布。
1.3 業(yè)務(wù)層
業(yè)務(wù)層的內(nèi)容其實(shí)特別多,很多技術(shù)其實(shí)都是在業(yè)務(wù)層出現(xiàn)問題后產(chǎn)生的一系列擴(kuò)展。聊這些內(nèi)容勢(shì)必就會(huì)帶來一些場(chǎng)景問題,這里我們淺淺了解一下,方便后續(xù)對(duì)Spring設(shè)計(jì)的理解。
假設(shè)現(xiàn)在有一個(gè)新增用戶的業(yè)務(wù),需要更新兩個(gè)表,sys_user表和sys_user_role表,這是一個(gè)很常見的業(yè)務(wù),那么現(xiàn)在假設(shè)sys_user更新成功,sys_user_role更新失敗,會(huì)出現(xiàn)什么問題?
實(shí)際就是創(chuàng)建用戶,界面提示新增失敗,但是查詢時(shí)可以查詢到這個(gè)用戶,這個(gè)用戶無法登錄【因?yàn)闆]有角色權(quán)限】,這就是很典型的事務(wù)問題,放到金融行業(yè),直接爆炸!?。?/p>
所以說像Spring自帶的日志模塊、事務(wù)模塊以及消息模塊等,都是服務(wù)于業(yè)務(wù)的。
1.4 持久層
說到持久層,不管是古早的JPA還是現(xiàn)在的Mybatis、Mybatis-plus都是基于JDBC,全稱為Java DataBase Connectivity(Java數(shù)據(jù)庫連接器)。
其實(shí)我們所說的JDBC只是規(guī)范,并非具體實(shí)現(xiàn),具體實(shí)現(xiàn)還是依靠各大數(shù)據(jù)庫廠商提供的驅(qū)動(dòng)。
下圖就是最原始的JDBC與上下游交互的交互邏輯。
JDBC架構(gòu).svg
JDBC開發(fā)步驟:
- 引入數(shù)據(jù)庫的驅(qū)動(dòng)jar包
 
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.27</version>
</dependency>- 獲取連接
 
DriverManager獲取連接
Class.forName("com.mysql.cj.jdbc.Driver");//注冊(cè)驅(qū)動(dòng)
String url = "jdbc:mysql://localhost:3306/test";
String username = "root";
String password = "123456";
Connection con = DriverManager.getConnection(url, username, password);- 獲取 Statement
 
用過獲取的連接,得到Statement
Statement stmt = con.createStatement();- 執(zhí)行sql
 
// 定義 sql 插入語句
String sql = "insert into person(id,name,gender,birthday)values(REPLACE(uuid(),'-',''),'測(cè)試人員','1','1997-09-23')";
// 定義 sql 更新語句
String sql = "update person t set t.gender = '2' where t.id='07382329976811f09ffbfa163e3e8fb6'";
// 定義 sql 刪除語句
String sql = "delete person t where t.id='07382329976811f09ffbfa163e3e8fb6'";
// 創(chuàng)建 sql 執(zhí)行對(duì)象
stmt = conn.createStatement();   
// 執(zhí)行查詢 sql 并返回更新條數(shù)
int count = stmt.executeUpdate(sql);String sql = "select * from person";
ResultSet rs = stmt.executeQuery(sql);后面為了簡(jiǎn)化開發(fā),衍生出來很多數(shù)據(jù)庫框架,詳細(xì)介紹就參考Spring Data JPA、MyBatis、Mybatis-plus。















 
 
 






 
 
 
 