架構探險——搭建框架

来源:http://www.cnblogs.com/solverpeng/archive/2016/06/26/5617906.html
-Advertisement-
Play Games

搭建輕量級Java Web框架快速搭建開發框架如何載入配置文件如何實現一個簡單的 IOC 容器如何載入指定的類如何初始化框架 *註解開發 目標:打造一個輕量級的 MVC 框架,Controller 是MVC的核心,類似於 SpringMVC。通過 Controller 註解來定義 Controlle ...


搭建輕量級Java Web框架
快速搭建開發框架
如何載入配置文件
如何實現一個簡單的 IOC 容器
如何載入指定的類
如何初始化框架

*註解開發

目標:
打造一個輕量級的 MVC 框架,Controller 是MVC的核心,類似於 SpringMVC。
通過 Controller 註解來定義 Controller 類,在該類中,可以通過 Inject 註解定義一系列 Service 成員變數,這就是"依賴註入"。
此外有一系列的被 Action 註解所定義的方法(Action方法),在這些Action方法中,調用了 Service 成員變數的方法來完成具體的業務邏輯。
若返回 View 對象,則表示 JSP 頁面;若返回 Data 對象,則表示一個 JSON 數據。

簡單來說,就是一個 Controller 類包含多個 Action方法,可以返回 View 或 Data 對象,分別對應JSP頁面或 JSON 數據。


@Controller 註解

@Service 註解

@Action 註解

@Inject 註解


View類:視圖路徑,模型數據

Data類:模型數據

Param類:封裝有請求參數的對象

Request對象:封裝請求信(請求方法和請求路徑)

Handler對象:封裝 Action信息(控制器類和處理方法)


核心:DispatchServlet:調用init方法時,初始化 Helper 類。service 方法中進行請求的獲取與請求的處理

PropUtil→ConfigHelper:載入配置項,獲取配置項定義的內容
ClassUtil→ClassHelper:獲取指定包名下所有類,所有 Controller 類,所有 Service 類,所有 Bean 類。(CLASS_SET容器的概念)
ReflectionUtil→BeanHelper:創建了一個 Bean 容器,在 BeanMap中存放了 Bean類和 Bean實例的映射關係。(BEAN_MAP就是一個容器)
IocHelper:實現依賴註入
ControllerHelper:處理請求和請求處理方法之間的關係(ACTION_MAP也是一個容器)。
HelperLoader:四個Helper類通過一個入口程式來載入,實際上是載入他們的靜態塊。


基礎:
定義框架配置項:
jdbc相關配置、項目基礎包名、JSP基礎路徑、靜態資源文件的基礎路徑
提供相關配置項常量

載入配置項,獲取配置項定義的內容:由 PropUtil 提供支持(從當前線程來載入配置文件)→ ConfigHelper


開發類載入器:
開發一個類載入器來載入基礎包名下的所有類,比如使用了某註解的類,或實現了某介面的類,再或者繼承了某父類的所有子類。

ClassUtil工具類:提供與類操作的相關方法,

獲取類載入器:只需要獲取當前線程中的ClassLoader即可
載入類:public static Class<?> forName(String className, boolean initialize,ClassLoader loader)。其中 initialize 表示是否載入靜態代碼塊。
獲取指定包名下的所有類。

獲取應用包名下的所有類、應用包名下的所有 Service 類,應用包名下的所有 Controller 類。
獲取 帶有 Controller 和 Service 類(Bean類,歸 IOC 容器去管理)→ ClassHelper


實現 Bean 容器(由容器來創建對象←通過反射結合ClassHelper來實現)

ReflectionUtil(反射工具類):創建實例,調用方法,設置成員變數的值
BeanHelper:獲取框架管理的 Bean 類,隨後通過反射工具類來創建實例。將每次創建的對象都放入到一個靜態的 Map<Class<?>, Object>類中。

實現依賴註入功能(通過容器對標註有某註解的成員變數進行實例化):
用 Inject 註解來實現對 Service 實例化。
具體實現:先通過BeanHelper獲取所有的BeanMap結構,記錄了類與對象的映射關係。然後遍歷這個映射關係,分別取出 Bean 類與Bean實例,
進而通過反射獲取類中所有的成員變數。繼續遍歷這些成員變數,看這些成員變數是否帶有 Inject 註解,若帶有該註解,則從 BeanMap 中,則從
BeanMap中根據Bean類取出Bean實例。最後通過 ReflectionUtil#setField 方法來修改當前成員變數的值。

載入Controller:
通過 ClassHelper,我們可以獲取所有定義了Controller 註解的類,可以通過反射獲取該類中所有帶有Action註解的方法(簡稱“Action”)方法,
獲取 Action 註解中的請求表達式,進而獲取請求方法和請求路徑,封裝一個請求對象(Request),和處理對象(handler) ,最後將 Request和Handler
建立一個映射關係,放入一個 ActionMap中,並提供一個可根據請求方法與請求路徑獲取處理對象的方法。

ControllerHelper:封裝一個 ActionMap,通過它存放Request和Handler之間的映射,然後通過 ClassHelper 來獲取所有帶有Controller註解的類,
接著遍歷這些 Controller 類,從 Action 註解中提取 URL,最後初始化 Request 和 Handler之間的映射。

核心:
請求轉發器(處理請求和響應):
處理所有請求,從HttpServletRequest對象中獲取請求方法和請求路徑。通過 ControllerHelper#getHandler方法來獲取Handler對象。
拿到 Handler 對象後,我們可以方便地獲取 Controller 的類,金額通過 BeanHelper.getBean 方法獲取 Controller 的實例對象。
隨後可以從 HttpServletRequest 對象中獲取所有請求參數,並將其初始化到一個 Param 的對象中。
還可以從 Handler 對象中獲取 Action 的方法返回值,該返回值可能有兩種情況:
(1)若返回值是 View 類型的視圖對象,則返回一個 JSP 頁面。
(2)若返回值是 Data 類型的數據對象,則返回一個 JSON 數據。

總結:
通過 Controller 註解定義了 Controller類,通過Inject 註解來實現依賴註入,通過Action註解來定義Action方法。
通過一系列的 Helper 類來初始化 MVC 框架。通過 DispatchServlet 來處理所有的請求,根據請求方法和請求路徑來調動具體的 Action 方法,判斷
Action 方法的返回值,若為 View類型,則條狀到 JSP 頁面,若為 Data類型,則返回 JSON 數據。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • php-resque是一個輕量級的消息隊列,讓我們一起來瞭解一下它的設計和使用 ...
  • HELLO WORLD! 今天第一次開立博客,專門記載學習編程語言中的點點滴滴。今日學習內容: 搭建vs code+ python3.5 "ide" 學習廖雪峰python教程-使用list和tuple 因為之前有pascal基礎,所以學起來不是很難理解,但是貴在堅持,自我激勵。昨天《墊底辣妹》給打 ...
  • 題目:輸入一個矩陣,按照從外向里以順時針的順序依次列印出每一個數字。 例如輸入以下矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次列印出數字 1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10 ...
  • 列印基本類型 以下列印基本的數據類型, 如int, char, float等, 最後兩行是以八進位和十六進位列印數字10 windows gcc輸出: 設置輸出寬度 設置每個整數占10個位置, 預設為右對齊 如果數字的長度比設置的寬度大, 那麼會忽略我們設置的輸出寬度 windows gcc輸出: ...
  • 英文原文:Micro Benchmarking with JMH: Measure, don’t guess!翻譯地址:使用JMH進行微基準測試:不要猜,要測試!原文作者:Antonio翻譯作者:Hollis轉載請註明出處。 很多Java開發人員都知道把一個變數聲明為null有助於垃圾回收(譯者註:... ...
  • 今天在寫框架的時候想把SaeMySQL初始化之後作為全局變數使用。但是後來發現PHP中的全局變數和Java或者OC中的全局變數還是有較大區別的。下麵記錄一下php裡面的global的使用相關註意事項。1.有些場合需要全局變數的出現,如下例子: 上面的代碼的結果為:"myname is" 。而不是期望 ...
  • 【課前思考】 1. 什麼是對象?什麼是類?什麼是包?什麼是介面?什麼是內部類? 2. 面向對象編程的特性有哪三個?它們各自又有哪些特性? 3. 你知道java語言在面向對象編程方面有何獨特的特點嗎? 難點: 1. 理解方法重載和方法重寫,不要混淆了兩者的使用。 2. 類變數和類方法的使用。 3. 接 ...
  • 前言: 目前在研究易信公眾號,想給公眾號增加一個獲取個人交通違章的查詢菜單,通過點擊返回查詢數據。以下是實施過程。 一、首先,用火狐瀏覽器打開XX省交管網,分析頁面信息: 可以看到共有4種查詢種類,我只要查詢違章數據,所以分析第一個電子警察信息查詢就好了,用firebug分別查看車牌號碼、車輛識別碼 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...