《深入分析JavaWeb技術內幕》之讀書筆記(篇三)
title: 《深入分析JavaWeb技術內幕》之讀書筆記(篇三)
tags: [Tomcat架構,設計模式,Spring設計與擴充套件點,SpringMVC工作機制,iBatis對映原理]
categories: 程式設計師技能
date: 2018-4-17 12:47:50
Tomcat的系統架構與設計模式
Tomcat總體結構
conf/server.xml配置檔案:
Tomcat的心臟即為Connector和Container元件:
往外層看,一個Container對應多個Connector(如圖有http和ajp等不同的Connetctor,Connector負責對外交流,接收請求,Container處理Connector接受的請求),它們共同組成一個Service,而多個Service就組成一個Server;
往裡層看,Container含有Engine(Servlet引擎),Engine含有Host(虛擬主機),Host含有Context(一個Context對應一個Web應用),Context含有Wrapper(一個Wrapper對應一個Servlet)。
Service類的實現類為StandardService
類。由於Service中,Container只有一個,Connector可多個,因此,StandardService提供setContainer()
方法用於設定Container(具體實現:去掉老Container與Service的關係,新增新Container與Service的關係,並一一新增Connector與新Containner的關係),以及addConnector()/removeConnector()
方法用於新增/刪除Connector(具體實現:在StandardService類中維護的connectors陣列中增減Connector)。
Server類的實現類為StandardServer
類。Server中可有多個Service,因此,StandardServer同樣提供addService()/removeService()
方法來增減Service,以及findService()
來供外部找到相應的Service。
Connector元件
Connector負責接收瀏覽器發過來的TCP連線請求,建立org.apache.coyote.Request
和org.apache.coyote.Response
用於交換資料,之後Container會建立一個新的執行緒,並接收到傳來的Request和Response物件,重新建立org.apache.catalina.connector.Request
和org.apache.catalina.connector.Response
物件,進行後續處理。
Container元件
Container使用了經典的責任鏈模式,即從Engine到Warpper,層層關聯。Engine作為頂層,不能呼叫setParent()
方法再設定父容器,但可以呼叫addChild()
方法新增子容器(且子容器只能是host);Wrapper作為最底層容器,也不能呼叫addChild()
方法新增子容器,但可以呼叫setParent()
方法設定父容器(且父容器只能是context)。
簡單的tomcat可以沒有Engine和Host。
Spring框架的設計理念與設計模式分析
核心元件
- Spring的核心元件即:Bean、Context、Core;
- 三者的形象比喻即:Bean是演員,Context是舞臺背景,Core是演出的道具。
- Bean即是Object的包裝,Context就是要發現每個Bean之間的關係,為他們建立好並維護這個關係,所以Context就是Bean關係的集合,這個關係集合又叫Ioc容器。而Core就是發現、建立、維護關係所需要的一系列工具,把Core元件看成Util更容易理解。
Spring Bean的建立是典型的工廠模式,頂級介面即BeanFactory,有三個子類,分別是:ListableBeanFactory
(表明bean是可列表的)、HierarchicalBeanFactory
(表明Bean是有繼承關係的,即每個Bean可能有父Bean)、AutowireCapableBeanFactory
(定義Bean的自動裝配規則),以上四個介面共同定義了Bean的集合、關係和行為。
Bean的完整定義在配置檔案的<bean/>
節點。當Spring成功解析一個Bean節點時,在spring的內部就會轉化為一個BeanDefnition物件,以後所有的操作都是在這個物件上進行的。
Ioc容器如何工作
如何建立BeanFactory
Ioc容器實際上是COntext元件結合其他兩個元件共同構建的一個Bean關係網。構建的入口即是AbstractApplicationContext類的refresh()
。
更新BeanFactory,首先就是如果BeanFactory已存在就更新,否則就建立,而更新的程式碼是,如果存在就destroyBeans()
並closeBeanFactory()
,然後createBeanFactory()
,建立的原始物件即是DefaultListableBeanFactory。並且後面會呼叫loadBeanDefinitions(beanFactory)
。前文說到Spring內部Bean被轉化為一個BeanDefnition物件,該方法即是載入、解析Bean的定義。
Ioc的擴充套件點
構建入口refresh()
的實現程式碼處,有這樣兩句關鍵程式碼,體現了Spring的擴充套件點:
//初始化和執行BeanFactoryPostProcessor beans
invokeBeanFactoryPostProcessors(beanFactory);
//初始化和執行BeanPostProcessor beans
registerBeanPostProcessors(beanFactory);
第二句程式碼主要是獲取實現BeanFactoryPostProcessor介面的子類,並執行它的postProcessBeanFactory()
方法,該方法顧名思義即是呼叫BeanFactory新增加工器,即當BeanFactory建立時被呼叫。這個方法引數需要傳入一個beanFactory(實際是ConfigurableListableBeanFactory,表示可配置的BeanFactory),說明可以對beanFactory做修改。
第四句程式碼,方法顧名思義是註冊Bean新增加工器,即該方法也是獲取實現了BeanPostProcessor介面的子類,並把它們(Bean新增加工器)註冊到BeanFactory物件的beanPostProcessors變數中。BeanPostProcessor介面定義了兩個方法:postProcessBeforeInitialization()
和postProcessAfterInitialization()
,每當bean物件初始化時,進行相關呼叫,執行使用者自定義的操作。
另外一個就是FactoryBean,這是一個工廠Bean,一個可以產生Bean的Bean。如果一個類繼承FactoryBean,使用者可以自己定義產生例項物件的方法,只需實現它的getObject()
方法即可。
由上,Spring的Ioc容器的擴充套件點主要有:
- BeanFactoryPostProcessor:構建BeanFactory時呼叫;
- BeanPostProcessor:構建Bean時呼叫;
- InitializingBean、DisposableBean:Bean例項建立和銷燬時呼叫;
- FactroyBean:可讓你建立自定義的物件,可實現更多的控制。
Spring中AOP的特性詳解
AOP即通過上面的FactoryBean來進行擴充套件來完成這個特性的。代理類繼承了FactoryBean的ProxyFactoryBean。
設計模式解析之代理模式
即給某一個物件建立一個代理物件,由這個代理物件控制對原物件的引用,代理物件可在呼叫原物件時增加一些額外操作。
Spring MVC的工作機制與設計模式
整體介紹
SpringMVC的嵌入關鍵就是通過配置Web.xml的servlet,核心類即DispatcherServlet,它繼承了HttpServlet,在Servlet的init方法呼叫時DispatcherServlet執行SpringMVC的初始化工作。具體初始化:
- initMultipartResolver:用於檔案上傳服務;
- initLocalResolver:用於處理應用的國際化;
- initThemeResolver:用於定義一個主題;
- initHandlerMappings:用於定義使用者設定的請求對映關係;
核心元件
- initHandelrAdapters:用於根據Handler的型別定義不同的處理規則;
核心元件
- initHandlerExceptionResolvers:當Handler處理出錯時,會通過這個Handler統一處理;
- initRequestToViewTranslator:將指定的ViewName按照定義的RequestToViewNameTranslator替換成想要的格式(如加上字首、字尾);
- initViewResolvers:用於將View解析成頁面。
核心元件
Control設計
Control=HandlerMapping+HandlerAdapters
HandlerMapping
HandlerMapping負責幫助我們管理URL和對應處理類(Handler)的對映關係,就是將一個或多個URL對映到一個或多個Spring Bean中。
它的初始化工作完成的兩個最重要的工作就是:將URL與Handler的對應關係儲存在handlerMap集合中,並將所有的interceptors物件儲存在adaptedInterceptors陣列中。
HandlerAdapter
HandlerAdapter用於幫助自定義各種Handler。一般的MVC框架會先定義一個特定介面,讓Handler去實現,然後MVC框架通過呼叫介面方法來呼叫Handler。而SpringMVC此處使用了多介面(如有:HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、SimpleServletHandlerAdapter等),不同介面定義不同方法,然後讓Handler去選擇實現這些個介面,讓Handelr的實現更加靈活。
它的初始化工作即是建立一個HandlerAdapter物件,將這個HandlerAdapter物件儲存在DispatcherServlet的handlerAdapters集合中。
整體呼叫邏輯
URL到來時,DispatcherServlet執行`doDispatch()`方法。
方法會匹配`DispatcherServlet的handlerMappings集合中的某個HandlerMapping物件的某個Handler`,匹配成功後返回一個HandlerExecutionChain物件(處理鏈,這個處理鏈包含使用者定義的多個HandlerInterceptor物件)。
通過呼叫該物件的`getHandler()`方法可以得到Handler物件,通過獲得的Handler物件進一步去匹配`支援該Handler的DispatcherServlet的handlerAdapters集合中的HandlerAdapter物件`,並返回handlerAdapter物件。
然後呼叫這個handlerAdapter物件的`handle()`方法(該方法需傳入Handler物件,並將Handler物件強轉為所繼承的父類,如上的Controller、HttpRequestHandler)。
`handle()`方法將呼叫強轉後的handler的`handleRequest()`方法,並返回ModelAndView物件,最後根據ModelAndView進行渲染。
Model設計
在業務邏輯層通常也有Model例項,不過此處所謂的Model,是指標對模版渲染的Model(ModelAndView)。
ModelAndView物件是連線業務邏輯層與View表現層的橋樑,對SpringMVC來說它也是連線Handler與View的橋樑。
Model顧名思義即會持有一個ModelMap物件和一個View物件(或View名稱)。在Handler中,將模板中需要的物件會存在這個ModelMap中,然後傳遞到View對應的ViewResolvers中,不同的ViewResovler對這個ModelMap中的物件有不同的處理方式。
View設計
View=RequestToViewNameTranslator+ViewResolver
RequestToViewNameTranslator用來支援使用者自定義對ViewName的解析,如給請求的ViewName加上字首或字尾,或替換成特定的字元等。
ViewResolver則是根據ViewName建立View物件。
設計模式解析之模板模式
核心即是:大的邏輯已經定義,要做的就是實現一些具體步驟。
SpringMVC的View設計使用了模板模式,View只定義了介面方法,AbstractView類實現了在View中定義的所有方法,並留有一個抽象方法renderMergedOutputModel給子類去實現。而子類AbstractJasperReportsView和AbstractTeamplateView抽象類實現了上述留有的方法,並進一步細化出了renderReport抽象方法和renderMergedTemplateModel方法給子類去進一步實現。
深入分析iBatis框架之系統架構與對映原理
左邊的SqlMapClient介面主要定義了客戶端的操作行為,包括select、insert、update和delete。而郵編主要定義了當前客戶端在當前執行緒中的執行環境。SqlMapSession可以共享使用,也可以自己建立,如果自己建立,需要在結束時自行關閉。
iBatis通過解析SqlMap配置檔案得到所有的Statement執行語句,同時會形成ParameterMap、ResultMap和SQL。當iBatis構建好RequestScope執行環境後,要做的工作就是把傳過來的物件資料結合ParameterMap中的資訊提取出一個引數陣列,這個陣列的順序對應與SQL中引數的順序,然後呼叫preparedStatement.setXXX(i,parameter)提交引數。
iBatis可以自己管理事務,也可以由外部管理。iBatis自己管理是通過共享SqlMapSession物件實現的,多個Statement執行時共享一個SqlMapSession例項,而且執行緒安全。如果外部程式管理就要自行控制SqlMapSession物件的生命週期。
設計模式解析之簡單工廠模式
核心即:通過判斷其條件,來返回不同的物件例項
iBatis中的DataExchangeFactory即使用了簡單工廠模式,它是一個工廠,它可根據傳遞進來的不同class型別返回不同的物件產品,這裡返回的產品都是單例,當然簡單工廠模式也可以每次建立一個新物件返回給呼叫者。
設計模式解析之工廠模式
與簡單工廠模式不同的是,這裡就不再是一個工廠,而是多個工廠,與一個頂層抽象工廠。如果把伺服器單機比作簡單工廠模式的工廠,那麼伺服器叢集+一個負載均衡伺服器就是工廠模式的多個工廠和頂層抽象工廠。
在iBatis中的DataSourceFacotry就是抽象工廠類,對應的JndiDataSourceFactory和DbcpDataSourceFactory就是具體工廠。
相關文章
- 《深入分析Java Web技術內幕》讀書筆記 - 第1章 深入Web請求過程JavaWeb筆記
- 《spring技術內幕》讀書筆記3-AOP的實現Spring筆記
- 深入分析 Java Web 技術內幕讀後總結JavaWeb
- 《ASP.Net Core技術內幕與專案實戰》讀書筆記_1ASP.NET筆記
- 讀《etcd 技術內幕》
- Spring技術內幕筆記(2):Spring MVC 與 WebSpring筆記MVCWeb
- 讀書筆記-大型網站技術架構筆記網站架構
- 《淘寶技術這十年》讀書筆記筆記
- AISecOps白皮書精華解讀之技術體系篇AI
- 讀書筆記】《PostgreSQL指南-內幕探索》-2.程式和記憶體架構筆記SQL記憶體架構
- JVM讀書筆記之OOMJVM筆記OOM
- Mysql技術內幕之InnoDB鎖探究MySql
- 【Laravel】Laravel 框架關鍵技術解析·讀書筆記(二)Laravel框架筆記
- 【讀書筆記】《PostgreSQL指南-內幕探索》-8.緩衝區管理器筆記SQL
- 【讀書筆記】《PostgreSQL指南-內幕探索》-7.堆內元組和僅索引掃描筆記SQL索引
- 《大型網站技術架構:核心原理與案例分析》讀書筆記 - 第3篇 案例網站架構筆記
- 《大型網站技術架構:核心原理與案例分析》讀書筆記 - 第1篇 概述網站架構筆記
- 《Maven實戰》之讀書筆記Maven筆記
- MySQL技術內幕之“日誌檔案”MySql
- 關於《深入分析JavaWeb技術內幕》中 跨域名共享Cookie的筆記(第二次看還是需要花點時間,遂將自己的理解寫下來)JavaWeb跨域Cookie筆記
- JVM讀書筆記之記憶體管理JVM筆記記憶體
- 《大型網站技術架構:核心原理與案例分析》讀書筆記 - 第2篇 架構網站架構筆記
- java核心技術閱讀筆記Java筆記
- 讀書筆記2-記憶體優化篇筆記記憶體優化
- ShowMeBug 核心技術內幕
- 讀書筆記筆記
- 程式設計師生存指南讀書筆記-第三篇(學習)程式設計師筆記
- 《數學之美》讀書筆記&思考筆記
- 深入探索Android熱修復技術原理讀書筆記 —— 程式碼熱修復技術Android筆記
- 深入探索Android熱修復技術原理讀書筆記 —— 資源熱修復技術Android筆記
- 深入探索Android熱修復技術原理讀書筆記 —— 熱修復技術介紹Android筆記
- 讀書筆記】《PostgreSQL指南-內幕探索》-3.2單表查詢的代價估計筆記SQL
- 【讀書筆記】《PostgreSQL指南-內幕探索》-3.3建立單表查詢的計劃樹筆記SQL
- 【Mysql技術內幕筆記--1】--Mysql體系結構和儲存引擎MySql筆記儲存引擎
- 《讀書與做人》讀書筆記筆記
- 讀書筆記3-卡頓優化篇筆記優化
- 讀書筆記5-資料儲存篇筆記
- 飛機的 PHP 學習筆記之應用技術篇PHP筆記