0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Spring 應用合并之路(一):摸石頭過河

京東云 ? 來源:京東科技 李君 ? 作者:京東科技 李君 ? 2024-10-28 11:11 ? 次閱讀

作者:京東科技 李君

公司最近一年在推進降本增效,在用盡各種手段之后,發(fā)現(xiàn)應用太多,每個應用都做跨機房容災部署,則最少需要 4 臺機器(稱為容器更合適)。那么,將相近應用做一個合并,減少維護項目,提高機器利用率就是一個可選方案。

?

經(jīng)過前后三次不同的折騰,最后探索出來一個可行方案。記錄一下,分享出來,希望對有相關(guān)需求的研發(fā)童鞋有所幫助。下面按照四種可能的方案,分別做介紹。另外,為了方便做演示,專門整了兩個演示項目:

?

??diguage/merge-demo-boot — 合并項目,下面簡稱為 boot。

??diguage/merge-demo-web — 被合并項目,下面簡稱為 web。

?

一、Jar 包引用

?

這個方式,可能是給人印象最容易的方式。仔細思考一下,從維護性的角度來看,這個方式反而是最麻煩的方式,理由如下:

?

1.web 項目每次更新,都需要重新打包發(fā)布新版; boot 項目也需要跟著更新發(fā)布。拉一次屎,脫兩次褲子。屬實麻煩。

2.還需要考慮 web 項目的加載問題,類似下面要描述的,是否共用容器:共用容器 — 這是最容器想到的方式。但是這種方式,需要解決 Bean 沖突的問題。不共用容器 — 這種方式需要處理 web 容器如何加載的問題。默認應該是無法識別。

3.?

基于這些考慮,這種方式直接被拋棄了。

?

二、倉庫合并,公用一套容器

?

這是第一次嘗試使用的方案。也是遇到問題最多的方案。

?

1.將兩個倉庫做合并。

1.將 web 倉庫的地址配置到 boot 項目里: git remote add web git@github.com:diguage/merge-demo-web.git;

2.在 boot 項目里,切出來一個分支: git switch -c web;

3.將 web 分支的提交清空: git update-ref -d HEAD,然后做一次提交;

4.將 web 項目的代碼克隆到 web 分支上: git pull --rebase --allow-unrelated-histories web master;注意,這里需要加 --allow-unrelated-histories 參數(shù),以允許不相干的倉庫進行合并。

5.從 boot 項目的 master 分支上,切出來一個合并分支: git switch -c merge;

6.將 web 項目向 boot 項目合并: git merge --allow-unrelated-histories web;注意,這里需要加 --allow-unrelated-histories 參數(shù),以允許不相干的倉庫進行合并。

7.處理代碼沖突,完成合并即可。

2.配置文件的合并于歸整。為了防止同名配置文件沖突,需要把 web 項目的配置文件調(diào)整到一個文件夾下,這里設定為 web 目錄。然后,需要把 web 項目的配置文件,讓 boot 可以加載到。這個調(diào)整相對簡單,只需要一個注解即可 @ImportResource({"classpath:web/spring-cfg.xml"})。

3.調(diào)整完配置文件,接著遇到的問題就是上面提到的 Bean 沖突的問題。由于兩個項目都訪問相同的數(shù)據(jù)庫, Dao 及 Service 層很多很多類都是同名的。另外,在 web 項目里,Dao 是基于 iBATIS 開發(fā)的,而在 boot 項目里,DAO 是基于 MyBATIS 開發(fā)的。所以,只能給 web 項目的相關(guān)代碼做重命名(嚴謹一點是給 Spring Bean 的 beanName 做重命名操作)。這又帶來了新問題:原來的項目里,注入方式是根據(jù)名稱注入的,就需要改動大量的代碼,給相關(guān)的 Bean 變量做重命名操作。這無形中增加了很多的復雜度和不確定性。

?

經(jīng)過不斷折騰,這種方式被迫放棄。

?

三、倉庫合并,Spring Boot 父子容器

?

在經(jīng)過上述方式折騰后,就想到了另外一個方案:可以考慮使用父子容器的方式來搞。接著就查到了這篇文章: Context Hierarchy with the Spring Boot Fluent Builder API。感覺這種方式挺不錯,就嘗試了一下。

?

1.代碼合并及文件調(diào)整,跟上述步驟類似,這個后面就不再贅述。

2.按照文章中的介紹,使用父子容器的方式來加載兩個項目。代碼如下:

3.原以為,這種方式屬于父子兩個容器,即使有同名的 Bean 應該也沒有影響。但是,經(jīng)過實踐才發(fā)現(xiàn),上面這個猜測是錯誤的。Spring Boot 在啟動的時候,它背后做了檢查,如果兩個容器有同名的 Bean,它也會報錯。也會帶來像上述方式那樣的大量重命名。折騰一兩天,最后還是放棄了這種寄予厚望的方式。

package com.diguage.demo.boot;

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

/**
 * @author D瓜哥 · https://www.diguage.com
 */
public class DemoBootApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder()
                .parent(BootConfig.class).web(WebApplicationType.NONE)
                .child(WebConfig.class)
                // 如果有第三個項目,可以作為子容器的兄弟容器加載。
                // .sibling(SiblingConfig.class)
                .run(args);
    }

    @Configuration
    @ImportResource({"classpath:spring-cfg.xml"})
    @ComponentScan(basePackages = "com.diguage.demo.boot")
    public static class BootConfig {
    }

    @Configuration
    @ImportResource({"classpath:web/spring-cfg.xml"})
    public static class WebConfig {
    }
}

?
Spring Boot 背后是否做了檢查,這個是根據(jù)報錯信息的猜測,沒有翻看代碼,所以這個猜測有一定的不確定性。有機會翻一下代碼,查看一下具體原因。

革命尚未成功,且聽下回分解……

下文:Spring 應用合并之路(二):峰回路轉(zhuǎn),柳暗花明?

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    336

    瀏覽量

    14280
收藏 人收藏

    評論

    相關(guān)推薦

    java spring教程

    java spring教程理解Spring 實現(xiàn)原理掌握Spring IOC,AOP掌握Spring的基礎配置和用法熟練使用SSH開發(fā)項目Sprin
    發(fā)表于 09-11 11:09

    什么是java spring

    什么是java springSpring是個開源框架,它由Rod Johnson創(chuàng)建。它是為了解決企業(yè)應用開發(fā)的復雜性而創(chuàng)建的。Spring使用基本的JavaBean來完成以前只可能由EJB完成
    發(fā)表于 09-11 11:16

    Spring工作原理

    2.AOP的主要原理:動態(tài)代理Spring工作原理Spring 已經(jīng)用過段時間了,感覺Spring是個很不錯的框架。內(nèi)部最核心的就是IOC了,動態(tài)注入,讓
    發(fā)表于 07-10 07:41

    Spring框架的設計理念

    Spring作為現(xiàn)在最優(yōu)秀的框架之,已被廣泛的使用,51CTO也曾經(jīng)針對Spring框架中的hqC應用做過報道。本文將從另外個視角試圖剖析出Sp
    發(fā)表于 07-15 08:17

    Spring筆記分享

    框架:高度抽取,可重用代碼的種設計高度的通用性多個可重用模塊的集合,形成某個領(lǐng)域的整體解決方案Spring => 容器框架包含并管理應用對象的生命周期IOC和SOP容器框架容器 =>
    發(fā)表于 11-04 07:51

    Spring認證」Spring Hello World 項目示例

    讓我們開始使用 Spring Framework 進行實際編程。在開始使用 Spring 框架編寫第個示例之前,您必須確保已按照Spring - 環(huán)境設置章節(jié)中的說明正確設置了
    發(fā)表于 08-17 13:49

    如何通過指針將字符串存放到高128字節(jié)?keil該怎樣設置?

    ;,str);結(jié)果沒有顯示。在keil里設置了存儲模式為large:varabes in PDATA也沒用。應該是那里沒設置好,以前直用匯編編程沒碰到這些事情,現(xiàn)在嘗試學習用C51編寫,好多地方都在石頭
    發(fā)表于 10-23 20:30

    spring教程ppt

    主要內(nèi)容Spring 概述Spring 整體結(jié)構(gòu)Spring實例Spring核心概念介紹控制反轉(zhuǎn)(IOC)依賴注入(DI)
    發(fā)表于 09-11 11:00 ?138次下載
    <b class='flag-5'>spring</b>教程ppt

    Skyworks逆襲靠什么?

    而在2002年由Alpha Industries和Conexant的無線通信部門合并而成的Skyworks則更像個摸著石頭過河的無名小輩,直到2009年Skyworks才決定集中精力發(fā)展射頻前端市場。
    的頭像 發(fā)表于 05-17 09:19 ?5284次閱讀
    Skyworks逆襲靠什么?

    Spring認證_什么是Spring GraphQL

    GraphQL 支持通過 HTTP 和 WebSocket 的 GraphQL 請求。 HTTP GraphQlHttpHandler 通過 HTTP 請求處理 GraphQL,并委托給 Web 攔截執(zhí)行請求。有兩種變體,種用于 Spring MVC,
    的頭像 發(fā)表于 08-06 14:30 ?664次閱讀
    <b class='flag-5'>Spring</b>認證_什么是<b class='flag-5'>Spring</b> GraphQL

    Spring認證」什么是Spring GraphQL?

    這個項目建立在 Boot 2.x 上,但它應該與最新的 Boot2.4.x5 相關(guān)。 要創(chuàng)建項目,請轉(zhuǎn)到start.spring.io并為要使用的GraphQL傳輸選擇啟動器: 啟動機 運輸 執(zhí)行
    的頭像 發(fā)表于 08-10 14:08 ?774次閱讀
    「<b class='flag-5'>Spring</b>認證」什么是<b class='flag-5'>Spring</b> GraphQL?

    為什么要學習Spring?Spring核心基礎教程詳解?

    為什么要學習Spring? Spring 框架是個開源的 Java 平臺。它最初由 Rod Johnson 編寫,并于 2003 年 6 月在 Apache 2.0 許可下首次發(fā)布。 Spr
    的頭像 發(fā)表于 08-11 16:00 ?568次閱讀
    為什么要學習<b class='flag-5'>Spring</b>?<b class='flag-5'>Spring</b>核心基礎教程詳解?

    Spring認證」Spring IoC 容器

    ,我們將在下章中討論。 容器通過讀取提供的配置元數(shù)據(jù)來獲取有關(guān)要實例化、配置和配置哪些對象的指令。數(shù)據(jù)可以由XML、Java注釋或Java代碼表示。下圖展示了Spring如何工作的高級視圖。 IoC
    的頭像 發(fā)表于 06-28 13:27 ?710次閱讀
    「<b class='flag-5'>Spring</b>認證」<b class='flag-5'>Spring</b> IoC 容器

    Spring認證是什么?

    Spring?Certified?Professional?2022 Spring Professional認證旨在測試和驗證學生對 SpringSpring Boot核心方面的
    的頭像 發(fā)表于 07-04 10:19 ?1245次閱讀
    <b class='flag-5'>Spring</b>認證是什么?

    Spring Boot 的設計目標

    什么是Spring Boot Spring Boot 是 Spring 開源組織下的個子項目,也是 Spring 組件
    的頭像 發(fā)表于 10-13 14:56 ?527次閱讀
    <b class='flag-5'>Spring</b> Boot 的設計目標