在這篇小文章中,我將嘗試解釋為什么我創建這個庫?以及它是如何實施的?
我為什么創建這個庫?
我在許多項目中使用了 Java EE 框架,其中大多數項目運行應用程序的可用資源沒有限制,但在極少數情況下,我們的資源有限,尤其是在部署服務上部署應用程序的內存,因此當應用程序超過限制時,部署服務將首先減慢應用程序的速度,然后如果繼續運行,服務將關閉它。我們使用傳統的 Spring 框架,甚至沒有 Spring Boot,我們嘗試使用不同的庫,但差異很小且毫無價值,這就是創建一個輕量級 Spring 替代方案,專注于盡可能減少內存消耗的想法的開始。 .
當我開始設計這個庫時,我腦子里只有兩個目標:
1 - 盡可能減少內存消耗
2 - 從學習的角度以及過渡本身的復雜性來看,嘗試盡可能多地使用現有的 Java EE API,以使向庫的過渡變得容易。
憑借這兩個目標,我成功地將其中一個應用程序的內存占用量減少了 40% 左右,并使過渡變得輕松快速,因為它與現有解決方案類似。
我是如何創建這個庫的?
這里是 GitHub 存儲庫,您可以在閱讀時檢查代碼。
整個庫有很多部分(截圖如下),大部分實現在主模塊中,主模塊也分為三種獨立模塊:Core、JPA、Web。 App 模塊主要用于集成,Plugin 模塊是一個 Maven 插件,可幫助在包存檔內創建必要的文件,以使庫正常工作
核心模塊
所以我們將從核心模塊開始,顧名思義,它包含庫的核心功能,即依賴注入或控制反轉。
為了實現這種功能,首先它首先在編譯階段掃描應用程序的類路徑,以查找庫應管理的所有帶注釋的類,以便為帶注釋的類創建組件定義。
組件定義基本上包含了我們稍后從此類實例化對象所需的所有信息,例如構造函數信息,如果有一些帶有注入注釋的setter(僅支持構造函數和setter注入)如果該類有一些接口或擴展其他類,我們將擁有從此類創建對象所需的所有信息(下面的屏幕截圖)。
然后,在掃描所有類路徑注釋并創建所需的所有組件定義后,我們將它們作為 JSON 文件存儲在類路徑中。
核心模塊的第二個也是主要功能是基于工廠設計模式的依賴注入和控制反轉,因此我們有ApplicationContext接口,它自身擴展了ComponentFactory接口,該接口的主要方法是getComponent 方法,將從組件名稱返回對象。
正如您首先在上面的屏幕截圖中看到的,我們嘗試檢查該組件是否存在于已初始化的 Singleton 組件中,如果不存在,那么我們首先從 JSON 文件中獲取組件定義,然后啟動 while 循環來獲取所有組件在將組件定義及其依賴項傳遞給組件組裝器以獲取準備注入的完整對象之前,先確定組件的依賴項。
JPA模塊
JPA 模塊的實現與 spring data JPA 非常相似,但非常少,之所以非常相似,是因為我在很多項目中使用了 spring data,并且我發現它很容易使用,正如我之前所說,我希望過渡到庫平滑并且需要盡可能少的工作,因此實現我自己的迷你 Spring 數據版本是最好的選擇。
實現圍繞 JpaRepository 接口,其中包含最常見的數據庫操作,如保存、刪除和 findAll...,為了使用 JPA 模塊,您需要擴展此接口并提供此接口應管理的實體及其 id ,然后在擴展接口并使用 Repository 注解進行注解后,您可以定義方法并使用 Query 注解對其進行注解并提供 JPQL 查詢,然后庫在編譯階段將創建一個實現該接口的功能齊全的類。
該庫還將管理應用程序的事務部分,因此從事務的角度來看,所有存儲庫接口和任何帶有事務注釋的類都將由庫管理。因此,對于任何事務組件,該庫將創建代理來管理基于 Transactional 注釋的事務,并且還將管理實體管理器生命周期。
網頁模塊
Web 模型負責管理應用程序的所有 Web 部分,根據設計,它是一個獨立的模塊,這意味著它可以獨立于庫中的其余模塊使用,通常它的用法與一些熟悉的 Java 非常相似EE 庫,例如 Spring web 或 Jax-rs。
實現是基于注釋的,你有用Controller注釋注釋的類,在這個控制器中你會找到用PathMapping注釋的方法,這些方法將根據一些標準(例如類型的類型)處理特定路徑或特定請求請求,內容類型...
從外面看,它與其他庫非常相似,但從內部看,它是不同的,因為該庫將在運行時更改這些Controller類,使它們全部擴展BaseHttpServlet,這也擴展了HttpServlet 并且它們將作為常規 servlet 工作。
如上面的截圖所示,首先我們在init方法中初始化組件,使用WebApplicationContext注入所有依賴項,然后我們將使用handleRequest方法處理傳入此Controller的所有請求,通過這種方法,我們將使用現有的 servlet api 來管理控制器,這將有助于保持較低的內存占用量,并減少開銷,因為該庫充當補充 servlet API 工作的插件。
首先,我們嘗試將請求映射到正確的方法,然后,我們嘗試通過從上下文或 HttpServletRequest 獲取信息(例如請求參數或標頭或路徑變量)來將所有請求的信息注入方法內或請求的正文...
我們轉換所有這些信息,然后在請求時將它們作為參數注入到方法中,然后我們執行該方法并根據 PathMapping 生成或內容類型(默認情況下為 application/Json)轉換結果或結果然后我們將內容寫入HttpServletResponse.
最后,如果流程中出現問題并拋出錯誤,我們會捕獲此錯誤或異常,并嘗試根據異常的類型進行處理,我們有異常處理程序來處理不同類型的異常,用戶可以還提供更多處理程序來按照他想要的方式處理任何異常。
Maven插件
最后也是重要的部分是 Maven 插件,它將創建應用程序正常工作以及構建 jar 或 war 包所需的所有文件。
首先插件將掃描類路徑和依賴項以搜索 component-definitions-json 文件,從該文件中它將生成:
lazy-application.json:包含應用程序的所有組件及其依賴項
lazy-application.properties:包含控制器和實體的列表,因此我們不需要在運行時掃描類路徑。
最后,如果包裝是罐子,我們將得到主類。
最后我們構建包存檔文件,其中包含應用程序代碼及其依賴項以及我們在上一步中生成的文件。
我盡量不深入細節,以使文章簡短且不那么復雜理解,當然代碼可以在 GitHub 上找到,這樣你也可以使用它。如果你有問題,請將其放在下面,我會盡力回答他們.
以上就是為什么我創建了一個輕量級迷你彈簧替代品以及我是如何做到的的詳細內容,更多請關注愛掏網 - it200.com其它相關文章!