最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java的osgi從基礎(chǔ)到實(shí)踐

 更新時(shí)間:2025年09月19日 16:19:20   作者:埃澤漫筆  
OSGi是Java的動態(tài)模塊化系統(tǒng),通過Bundle實(shí)現(xiàn)模塊化部署與依賴管理,支持運(yùn)行時(shí)動態(tài)安裝、更新和卸載,提供服務(wù)注冊與發(fā)現(xiàn)機(jī)制,解決JAR地獄問題,適用于企業(yè)級和嵌入式系統(tǒng)開發(fā),本文給大家介紹Java的osgi從基礎(chǔ)到實(shí)踐,感興趣的朋友一起看看吧

題目詳細(xì)答案

OSGi 是一個(gè)模塊化系統(tǒng)和服務(wù)平臺,主要用于 Java。它定義了一種動態(tài)模塊系統(tǒng),使得 Java 應(yīng)用程序可以被分解成多個(gè)模塊(稱為“bundles”),并且這些模塊可以在運(yùn)行時(shí)被安裝、啟動、停止、更新和卸載。OSGi 被廣泛應(yīng)用于構(gòu)建靈活和可擴(kuò)展的應(yīng)用程序,尤其是在大型企業(yè)級應(yīng)用和嵌入式系統(tǒng)中。

OSGi 的核心概念

Bundle

Bundle 是 OSGi 的基本部署單元,相當(dāng)于一個(gè) Java JAR 文件,但包含額外的元數(shù)據(jù),用于描述它的依賴關(guān)系和服務(wù)。每個(gè) Bundle 都有一個(gè)唯一的標(biāo)識符和版本號。

Bundle Lifecycle

OSGi 管理每個(gè) Bundle 的生命周期,包括安裝、解析、啟動、停止、更新和卸載等狀態(tài)。Bundle 可以在運(yùn)行時(shí)動態(tài)地進(jìn)行這些狀態(tài)轉(zhuǎn)換。

Service Registry:

OSGi 提供了一個(gè)服務(wù)注冊表,用于在 Bundle 之間共享對象(服務(wù))。Bundle 可以注冊、查找和使用服務(wù),這些服務(wù)是實(shí)現(xiàn)了特定接口的對象。

Module Layer:

OSGi 定義了一個(gè)模塊層,用于管理 Bundle 之間的依賴關(guān)系和類加載。每個(gè) Bundle 都有自己的類加載器,確保模塊之間的隔離和獨(dú)立性。

Declarative Services:

OSGi 提供了聲明式服務(wù)(Declarative Services, DS),簡化了服務(wù)的聲明和綁定。使用 XML 配置文件或注解來聲明服務(wù)的依賴關(guān)系和生命周期。

OSGi 的優(yōu)勢

  1. 模塊化:提供了清晰的模塊化機(jī)制,使得應(yīng)用程序可以被分解為松散耦合的模塊,提高了代碼的可維護(hù)性和可擴(kuò)展性。
  2. 動態(tài)性:支持在運(yùn)行時(shí)動態(tài)地安裝、更新和卸載模塊,這對于需要高可用性和靈活性的應(yīng)用程序非常有用。
  3. 服務(wù)導(dǎo)向:提供了強(qiáng)大的服務(wù)注冊和發(fā)現(xiàn)機(jī)制,使得模塊之間可以通過服務(wù)進(jìn)行通信和協(xié)作。
  4. 版本管理:支持模塊的版本管理,允許不同版本的模塊共存,避免版本沖突。

OSGi Demo

1. 創(chuàng)建一個(gè) Bundle

首先,創(chuàng)建一個(gè)包含META-INF/MANIFEST.MF文件的 JAR 包。MANIFEST.MF文件包含 Bundle 的元數(shù)據(jù):

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Example Bundle
Bundle-SymbolicName: com.example.bundle
Bundle-Version: 1.0.0
Import-Package: org.osgi.framework

2. 注冊一個(gè)服務(wù)

創(chuàng)建一個(gè)接口HelloService:

package com.example.service;
public interface HelloService {
    void sayHello();
}

然后創(chuàng)建一個(gè)實(shí)現(xiàn)類HelloServiceImpl:

package com.example.service.impl;
import com.example.service.HelloService;
public class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("Hello, OSGi World!");
    }
}

最后,在 Bundle 的Activator類中注冊服務(wù):

package com.example;
import com.example.service.HelloService;
import com.example.service.impl.HelloServiceImpl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
    @Override
    public void start(BundleContext context) throws Exception {
        HelloService helloService = new HelloServiceImpl();
        context.registerService(HelloService.class.getName(), helloService, null);
        System.out.println("HelloService registered");
    }
    @Override
    public void stop(BundleContext context) throws Exception {
        System.out.println("Bundle stopped");
    }
}

3. 使用 Declarative Services

使用聲明式服務(wù)可以簡化服務(wù)的聲明和管理。創(chuàng)建一個(gè)HelloService的實(shí)現(xiàn)類并使用注解聲明服務(wù):

package com.example.service.impl;
import com.example.service.HelloService;
import org.osgi.service.component.annotations.Component;
@Component
public class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("Hello, OSGi World!");
    }
}

OSGi 詳解:Java 模塊化與動態(tài)服務(wù)平臺

OSGi(Open Service Gateway Initiative)是一套基于 Java 的模塊化系統(tǒng)規(guī)范,旨在解決大型 Java 應(yīng)用的模塊化拆分、動態(tài)擴(kuò)展和服務(wù)協(xié)作問題。它通過定義嚴(yán)格的模塊邊界、依賴管理和服務(wù)注冊機(jī)制,使應(yīng)用程序能夠拆分為獨(dú)立的 “Bundle”(模塊),并支持模塊在運(yùn)行時(shí)的動態(tài)安裝、更新和卸載。本文將深入解析 OSGi 的核心概念、工作原理、優(yōu)勢及實(shí)戰(zhàn)示例。

一、OSGi 的核心定位與價(jià)值

在傳統(tǒng) Java 應(yīng)用中,“JAR 地獄”(Jar Hell)是常見痛點(diǎn):多個(gè) JAR 包可能包含同名類、版本沖突,或依賴關(guān)系混亂導(dǎo)致的 “牽一發(fā)而動全身”。OSGi 通過以下方式解決這些問題:

  • 強(qiáng)模塊化:明確模塊的邊界和依賴,避免類沖突;
  • 動態(tài)性:支持模塊在運(yùn)行時(shí)(無需重啟應(yīng)用)更新,適合高可用場景;
  • 服務(wù)化協(xié)作:模塊間通過 “服務(wù)” 松耦合通信,而非直接依賴實(shí)現(xiàn)類。

OSGi 廣泛應(yīng)用于需要靈活擴(kuò)展的場景:Eclipse IDE(基于 OSGi 構(gòu)建)、物聯(lián)網(wǎng)設(shè)備、企業(yè)級中間件、車載系統(tǒng)等。

二、OSGi 核心概念

1. Bundle:OSGi 的基本部署單元

Bundle 是 OSGi 中最小的功能模塊,本質(zhì)是一個(gè)包含額外元數(shù)據(jù)的 JAR 包。與普通 JAR 相比,其META-INF/MANIFEST.MF文件包含描述模塊身份、依賴和能力的關(guān)鍵信息。

核心元數(shù)據(jù)字段(MANIFEST.MF):

字段

作用

Bundle-ManifestVersion

聲明 OSGi 規(guī)范版本(通常為 2,對應(yīng) OSGi R4 及以上)

Bundle-SymbolicName

模塊的唯一標(biāo)識符(類似 Java 包名,如com.example.user.service

),必須全局唯一

Bundle-Version

模塊版本(如1.0.0

),用于版本管理和沖突解決

Export-Package

聲明模塊對外暴露的包(其他模塊可導(dǎo)入),如com.example.service;version=1.0

Import-Package

聲明模塊依賴的外部包(需其他模塊導(dǎo)出),如org.osgi.framework;version="[1.9,2.0)"

Bundle-Activator

指定模塊的激活器類(用于模塊啟動 / 停止時(shí)執(zhí)行初始化邏輯)

示例MANIFEST.MF:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: User Service Bundle
Bundle-SymbolicName: com.example.user.service
Bundle-Version: 1.0.0
Export-Package: com.example.user.api;version=1.0.0
Import-Package: org.osgi.framework;version="[1.9,2.0)",
 org.osgi.service.component.annotations;version="[1.4,2.0)"
Bundle-Activator: com.example.user.service.Activator

2. Bundle 生命周期:動態(tài)狀態(tài)管理

OSGi 為每個(gè) Bundle 定義了嚴(yán)格的生命周期狀態(tài),支持運(yùn)行時(shí)動態(tài)切換,狀態(tài)轉(zhuǎn)換由 OSGi 容器(如 Equinox、Felix)管理。

核心狀態(tài)及轉(zhuǎn)換:
  • 安裝(Installed):Bundle 已被加載到容器,但未解析依賴。
  • 解析(Resolved):容器驗(yàn)證 Bundle 的依賴(Import-Package)已滿足,類加載器就緒。
  • 啟動(Active):Bundle 處于運(yùn)行狀態(tài),激活器的start()方法已執(zhí)行,可提供服務(wù)。
  • 停止(Stopped):Bundle 暫時(shí)停止,激活器的stop()方法已執(zhí)行,服務(wù)已注銷。
  • 卸載(Uninstalled):Bundle 從容器中移除,資源被釋放。
狀態(tài)轉(zhuǎn)換觸發(fā):
  • 安裝:bundleContext.installBundle("file:user-service.jar");
  • 啟動:bundle.start()
  • 停止:bundle.stop();
  • 卸載:bundle.uninstall()。

3. 服務(wù)注冊表(Service Registry):模塊協(xié)作的核心

OSGi 通過 “服務(wù)注冊表” 實(shí)現(xiàn) Bundle 間的間接通信:模塊可將對象(服務(wù))注冊到注冊表,其他模塊通過接口查找并使用服務(wù),無需依賴具體實(shí)現(xiàn)類。

服務(wù)生命周期:
  1. 注冊:Bundle 通過BundleContext.registerService()將實(shí)現(xiàn)類注冊為服務(wù)(關(guān)聯(lián)接口);
  2. 發(fā)現(xiàn):其他 Bundle 通過BundleContext.getServiceReference(接口名)查找服務(wù)引用;
  3. 使用:通過BundleContext.getService(服務(wù)引用)獲取服務(wù)實(shí)例并調(diào)用方法;
  4. 注銷:Bundle 停止時(shí),注冊的服務(wù)自動注銷(或手動調(diào)用ungetService())。
示例:注冊與使用服務(wù)
// 1. 定義服務(wù)接口(需被Export-Package暴露)
package com.example.user.api;
public interface UserService {
    String getUsername(Long id);
}
// 2. 實(shí)現(xiàn)服務(wù)
package com.example.user.impl;
import com.example.user.api.UserService;
public class UserServiceImpl implements UserService {
    @Override
    public String getUsername(Long id) {
        return "user_" + id; // 模擬查詢
    }
}
// 3. 注冊服務(wù)(在Activator中)
package com.example.user.service;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import com.example.user.api.UserService;
import com.example.user.impl.UserServiceImpl;
public class Activator implements BundleActivator {
    @Override
    public void start(BundleContext context) {
        // 注冊服務(wù):關(guān)聯(lián)接口、實(shí)現(xiàn)類、屬性(可選)
        context.registerService(
            UserService.class.getName(), 
            new UserServiceImpl(), 
            null // 服務(wù)屬性(如版本、描述)
        );
        System.out.println("UserService registered");
    }
    @Override
    public void stop(BundleContext context) {
        System.out.println("UserService bundle stopped");
    }
}
// 4. 其他Bundle使用服務(wù)
package com.example.order.service;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import com.example.user.api.UserService;
public class OrderActivator implements BundleActivator {
    private ServiceReference<UserService> userServiceRef;
    private UserService userService;
    @Override
    public void start(BundleContext context) {
        // 查找服務(wù)引用
        userServiceRef = context.getServiceReference(UserService.class);
        if (userServiceRef != null) {
            // 獲取服務(wù)實(shí)例
            userService = context.getService(userServiceRef);
            // 使用服務(wù)
            String username = userService.getUsername(100L);
            System.out.println("Found username: " + username); // 輸出 "user_100"
        }
    }
    @Override
    public void stop(BundleContext context) {
        // 釋放服務(wù)
        if (userServiceRef != null) {
            context.ungetService(userServiceRef);
        }
    }
}

4. 模塊層(Module Layer):類加載與依賴隔離

OSGi 的模塊層通過獨(dú)立類加載器實(shí)現(xiàn)模塊隔離,解決傳統(tǒng) Java“類路徑(classpath)全局可見” 導(dǎo)致的沖突問題。

類加載規(guī)則:
  • 每個(gè) Bundle 有自己的類加載器,僅能加載:
    • 自身包含的類;
    • 通過Import-Package導(dǎo)入的其他 Bundle 的類(需被對方Export-Package暴露);
    • OSGi 框架提供的系統(tǒng)類(如org.osgi.framework)。
  • 類加載遵循 “雙親委派模型”:先委托父加載器(框架類加載器),再嘗試自己加載。
依賴管理:
  • 顯式依賴:通過Import-Package聲明依賴的包及版本范圍(如com.example.user.api;version="[1.0,2.0)"),容器會自動匹配導(dǎo)出該包的 Bundle;
  • 版本兼容:支持 “語義化版本”,如[1.0,2.0)表示兼容 1.x 版本,不兼容 2.0 及以上。

5. 聲明式服務(wù)(Declarative Services, DS):簡化服務(wù)開發(fā)

手動管理服務(wù)注冊 / 查找需編寫大量模板代碼,OSGi 的聲明式服務(wù)(DS)通過注解或 XML 配置自動處理服務(wù)生命周期,降低開發(fā)復(fù)雜度。

核心注解(DS 1.4+):
  • @Component:標(biāo)記類為服務(wù)組件,自動注冊為服務(wù);
  • @Reference:聲明對其他服務(wù)的依賴,容器自動注入;
  • @Activate/@Deactivate:標(biāo)記組件激活 / 鈍化時(shí)執(zhí)行的方法。
示例:DS 注解開發(fā)服務(wù)
// 服務(wù)接口(同上,需Export)
package com.example.user.api;
public interface UserService {
    String getUsername(Long id);
}
// 服務(wù)實(shí)現(xiàn)(DS自動注冊)
package com.example.user.impl;
import org.osgi.service.component.annotations.Component;
import com.example.user.api.UserService;
// @Component:自動注冊為UserService服務(wù)
@Component(service = UserService.class)
public class UserServiceImpl implements UserService {
    @Override
    public String getUsername(Long id) {
        return "user_" + id;
    }
}
// 依賴服務(wù)的組件(DS自動注入)
package com.example.order.impl;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import com.example.user.api.UserService;
@Component
public class OrderProcessor {
    // @Reference:自動注入U(xiǎn)serService實(shí)例
    @Reference
    private UserService userService;
    @Activate // 組件激活時(shí)執(zhí)行
    public void activate() {
        String username = userService.getUsername(200L);
        System.out.println("Order user: " + username); // 輸出 "user_200"
    }
}

DS 的優(yōu)勢在于:無需編寫 Activator,服務(wù)依賴自動管理,組件生命周期與服務(wù)可用性動態(tài)綁定(如依賴服務(wù)消失時(shí),組件自動鈍化)。

三、OSGi 的核心優(yōu)勢

  1. 嚴(yán)格的模塊化隔離
    通過Export-Package/Import-Package和獨(dú)立類加載器,確保模塊間僅通過顯式暴露的接口交互,避免類沖突和依賴混亂。
  2. 運(yùn)行時(shí)動態(tài)性
    支持 Bundle 的熱部署(安裝 / 更新 / 卸載無需重啟應(yīng)用),適合高可用場景(如服務(wù)器、物聯(lián)網(wǎng)設(shè)備)。
  3. 服務(wù)化的松耦合
    模塊通過接口而非實(shí)現(xiàn)類協(xié)作,更換服務(wù)實(shí)現(xiàn)時(shí)無需修改依賴方代碼,提高擴(kuò)展性。
  4. 精細(xì)的版本管理
    支持同一 Bundle 不同版本共存,通過版本范圍控制依賴兼容性,解決 “升級即崩潰” 問題。
  5. 動態(tài)服務(wù)感知
    服務(wù)注冊 / 注銷時(shí),依賴方會收到通知(如 DS 的@Reference自動更新),適應(yīng)服務(wù)動態(tài)變化。

四、OSGi 實(shí)戰(zhàn):開發(fā)與運(yùn)行環(huán)境

1. 主流 OSGi 容器

  • Eclipse Equinox:Eclipse IDE 使用的 OSGi 實(shí)現(xiàn),兼容性好,工具鏈完善;
  • Apache Felix:輕量級 OSGi 容器,適合嵌入式場景;
  • Knopflerfish:專注于嵌入式系統(tǒng)的 OSGi 實(shí)現(xiàn)。

2. 開發(fā)工具

  • Eclipse PDE:專門用于 OSGi 開發(fā)的插件,支持 Bundle 創(chuàng)建、依賴管理和調(diào)試;
  • Maven + bnd-maven-plugin:通過 Maven 構(gòu)建 Bundle,自動生成MANIFEST.MF。

3. 運(yùn)行流程示例

  1. 編寫服務(wù)接口 Bundle(導(dǎo)出接口包);
  2. 編寫服務(wù)實(shí)現(xiàn) Bundle(導(dǎo)入接口包,注冊服務(wù));
  3. 編寫消費(fèi) Bundle(導(dǎo)入接口包,使用服務(wù));
  4. 將 Bundle 打包為 JAR,通過容器命令安裝并啟動:bash
# Apache Felix示例:啟動容器后執(zhí)行
install file:user-api.jar   # 安裝接口Bundle
install file:user-impl.jar  # 安裝實(shí)現(xiàn)Bundle
install file:order-impl.jar # 安裝消費(fèi)Bundle
start 1 2 3                 # 啟動Bundle(1、2、3為Bundle ID)

五、OSGi 的挑戰(zhàn)與適用場景

挑戰(zhàn):

  • 學(xué)習(xí)曲線陡峭:需理解生命周期、服務(wù)注冊、類加載等復(fù)雜概念;
  • 配置復(fù)雜MANIFEST.MF或 DS 配置需嚴(yán)格遵循規(guī)范,易出錯;
  • 性能開銷:額外的類加載和服務(wù)管理邏輯可能增加少量運(yùn)行時(shí)開銷。

適用場景:

  • 大型企業(yè)級應(yīng)用:需模塊化拆分和團(tuán)隊(duì)并行開發(fā);
  • 高可用系統(tǒng):需支持熱更新(如金融交易系統(tǒng)、服務(wù)器中間件);
  • 嵌入式 / 物聯(lián)網(wǎng)設(shè)備:資源有限,需動態(tài)擴(kuò)展功能(如智能家居網(wǎng)關(guān));
  • 插件化平臺:如 IDE(Eclipse)、CMS 系統(tǒng),支持第三方插件擴(kuò)展。

六、總結(jié)

OSGi 通過強(qiáng)模塊化、動態(tài)服務(wù)和版本管理,為 Java 應(yīng)用提供了靈活的拆分與協(xié)作方案,尤其適合需要長期維護(hù)、動態(tài)擴(kuò)展的大型系統(tǒng)。盡管存在學(xué)習(xí)成本,但在解決 “JAR 地獄”、支持熱部署和松耦合服務(wù)方面的優(yōu)勢,使其在企業(yè)級開發(fā)和嵌入式領(lǐng)域仍被廣泛采用。

理解 OSGi 的核心概念(Bundle、服務(wù)注冊表、DS)是掌握其用法的關(guān)鍵,而結(jié)合具體容器(如 Equinox)的實(shí)戰(zhàn)練習(xí),能更深入體會其動態(tài)模塊化的價(jià)值。

到此這篇關(guān)于Java的osgi從基礎(chǔ)到實(shí)踐的文章就介紹到這了,更多相關(guān)Java的osgi內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 小白必看toString(),String.valueOf,(String)強(qiáng)轉(zhuǎn)

    小白必看toString(),String.valueOf,(String)強(qiáng)轉(zhuǎn)

    在Java中,往往需要把一個(gè)類型的變量轉(zhuǎn)換成String 類型,本文主要介紹了toString(),String.valueOf,(String)強(qiáng)轉(zhuǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Java中的線程安全集合CopyOnWriteArrayList解析

    Java中的線程安全集合CopyOnWriteArrayList解析

    這篇文章主要介紹了Java中的線程安全CopyOnWriteArrayList解析,CopyOnWriteArrayList是ArrayList的線程安全版本,從他的名字可以推測,CopyOnWriteArrayList是在有寫操作的時(shí)候會copy一份數(shù)據(jù),然后寫完再設(shè)置成新的數(shù)據(jù),需要的朋友可以參考下
    2023-12-12
  • Java的并發(fā)編程之CyclicBarrier解析

    Java的并發(fā)編程之CyclicBarrier解析

    這篇文章主要介紹了Java的并發(fā)編程之CyclicBarrier解析,CyclicBarrier支持一個(gè)可選的Runnable命令,在一組線程中的最后一個(gè)線程到達(dá)之后(但在釋放所有線程之前),該命令只在每個(gè)屏障點(diǎn)運(yùn)行一次,需要的朋友可以參考下
    2023-11-11
  • Spring中@Configuration和@Component注解的區(qū)別及原理

    Spring中@Configuration和@Component注解的區(qū)別及原理

    這篇文章主要介紹了Spring中@Configuration和@Component注解的區(qū)別及原理,從功能上來講,這些注解所負(fù)責(zé)的功能的確不相同,但是從本質(zhì)上來講,Spring內(nèi)部都將其作為配置注解進(jìn)行處理,需要的朋友可以參考下
    2023-11-11
  • 全面解析JTA 深度歷險(xiǎn)

    全面解析JTA 深度歷險(xiǎn)

    本文介紹了利用 JTA 深度歷險(xiǎn)的相關(guān)內(nèi)容,充分舉例說明JTA的原理和事務(wù)處理等相關(guān)內(nèi)容,十分詳細(xì),需要的朋友可以參考下。
    2017-09-09
  • Java 中一個(gè)類提供一個(gè)默認(rèn)對象的多種方法

    Java 中一個(gè)類提供一個(gè)默認(rèn)對象的多種方法

    這篇文章主要介紹了Java 中一個(gè)類提供一個(gè)默認(rèn)對象的多種方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Java?JUC并發(fā)之.util.concurrent并發(fā)工具包使用指南

    Java?JUC并發(fā)之.util.concurrent并發(fā)工具包使用指南

    JUC就是java.util .concurrent工具包的簡稱,這是一個(gè)處理線程的工具包,JDK 1.5開始出現(xiàn)的,這篇文章主要介紹了Java?JUC并發(fā)之.util.concurrent并發(fā)工具包使用的相關(guān)資料,需要的朋友可以參考下
    2025-08-08
  • idea中同一SpringBoot項(xiàng)目多端口啟動

    idea中同一SpringBoot項(xiàng)目多端口啟動

    本文主要介紹了idea中同一SpringBoot項(xiàng)目多端口啟動,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • (starters)springboot-starter整合阿里云datahub方式

    (starters)springboot-starter整合阿里云datahub方式

    這篇文章主要介紹了(starters)springboot-starter整合阿里云datahub方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java中使用模板引擎+Word XML導(dǎo)出復(fù)雜Word的步驟

    Java中使用模板引擎+Word XML導(dǎo)出復(fù)雜Word的步驟

    這篇文章主要介紹了如何利用Word XML及模板引擎生成復(fù)雜Word文檔,先設(shè)計(jì)樣式和固定內(nèi)容的Word文檔,保存為XML格式;在需要插入動態(tài)數(shù)據(jù)的地方添加模板占位符;使用Java讀取XML文件,通過模板引擎如FreeMarker或Velocity填充數(shù)據(jù),最終生成新的Word文檔
    2026-04-04

最新評論

古交市| 麻江县| 中超| 栖霞市| 秀山| 上林县| 枞阳县| 克什克腾旗| 科技| 霸州市| 临颍县| 天长市| 长泰县| 墨脱县| 涟水县| 红桥区| 锡林郭勒盟| 攀枝花市| 长武县| 门头沟区| 孟津县| 行唐县| 石首市| 修武县| 泰安市| 藁城市| 泰兴市| 台湾省| 都匀市| 承德市| 班玛县| 祁东县| 博客| 九台市| 和田市| 肥城市| 广安市| 睢宁县| 富源县| 黑龙江省| 甘孜县|