当前位置: 首页 > news >正文

2.4 构建模块化应用


第4章:构建模块化应用

模块化应用是 JDK 9 的核心特性之一,通过模块化系统(Project Jigsaw)实现代码的强封装和显式依赖管理。本章详细讲解如何从零构建一个模块化应用,包括模块定义、编译、打包、运行及调试。


4.1 模块化应用开发流程
  1. 定义模块:编写 module-info.java 声明模块元数据。
  2. 组织代码:按模块化结构组织源代码。
  3. 编译模块:使用 javac 编译模块。
  4. 打包模块:将模块打包为模块化 JAR。
  5. 运行模块:使用 java 命令运行模块化应用。
  6. 调试与优化:使用工具(如 jdeps)分析依赖关系。

4.2 模块化应用实战
场景:构建一个简单的模块化应用,包含以下模块:
  1. com.utils:工具模块,提供字符串处理工具。
  2. com.user:用户模块,依赖 com.utils,导出用户模型。

4.3 步骤详解
步骤1:定义模块
  1. com.utils 模块

    • 模块描述符
      // com.utils/module-info.java
      module com.utils {exports com.utils; // 导出工具包
      }
      
    • 工具类
      // com.utils/com/utils/StringUtil.java
      package com.utils;public class StringUtil {public static String capitalize(String s) {return s.substring(0, 1).toUpperCase() + s.substring(1);}
      }
      
  2. com.user 模块

    • 模块描述符
      // com.user/module-info.java
      module com.user {requires com.utils; // 依赖工具模块exports com.user.model; // 导出用户模型包
      }
      
    • 用户类
      // com.user/com/user/model/User.java
      package com.user.model;import com.utils.StringUtil;public class User {private String name;public User(String name) {this.name = StringUtil.capitalize(name);}public String getName() { return name; }
      }
      

步骤2:组织代码结构
src/
├── com.utils/
│   ├── module-info.java
│   └── com/utils/
│       └── StringUtil.java
└── com.user/├── module-info.java└── com/user/└── model/└── User.java

步骤3:编译模块

使用 javac 编译模块,指定模块源路径和输出目录:

javac -d out --module-source-path src --module com.utils,com.user

编译后的目录结构

out/
├── com.utils/
│   ├── module-info.class
│   └── com/utils/
│       └── StringUtil.class
└── com.user/├── module-info.class└── com/user/└── model/└── User.class

步骤4:打包模块

将模块打包为模块化 JAR:

# 打包 com.utils 模块
jar --create --file mods/com.utils.jar -C out/com.utils .# 打包 com.user 模块
jar --create --file mods/com.user.jar -C out/com.user .

打包后的目录结构

mods/
├── com.utils.jar
└── com.user.jar

步骤5:运行模块化应用

使用 java 命令运行模块化应用,指定模块路径和主模块:

java --module-path mods -m com.user/com.user.model.User

步骤6:调试与优化
  1. 使用 jdeps 分析依赖

    jdeps --module-path mods -s mods/com.user.jar
    # 输出示例:
    com.user -> com.utils
    com.user -> java.base
    
  2. 生成模块图

    jdeps --module-path mods --dot-output dots mods/com.user.jar
    
    • 生成 dots/com.user.dot 文件,可用 Graphviz 工具生成依赖图。

4.4 模块化应用最佳实践
1. 最小化模块导出
  • 仅导出必要的包,隐藏实现细节。
  • 示例:
    module com.myapp {exports com.myapp.api; // 仅导出API包
    }
    
2. 使用传递依赖
  • 通过 requires transitive 声明传递依赖,避免重复依赖。
  • 示例:
    module com.myapp {requires transitive com.utils; // 传递依赖
    }
    
3. 适配反射框架
  • 使用 opens 开放反射访问权限,支持 Spring/Hibernate 等框架。
  • 示例:
    module com.myapp {opens com.myapp.internal to spring.core; // 允许Spring反射访问
    }
    
4. 生成定制化 JRE
  • 使用 jlink 生成仅包含所需模块的最小化 JRE。
  • 示例:
    jlink --module-path $JAVA_HOME/jmods:mods \--add-modules com.user,java.base \--output myapp-runtime
    

4.5 常见问题与解决
问题解决方案
模块未找到(Module not found)检查模块路径(--module-path)是否包含依赖模块,确认 requires 声明正确。
无法访问非导出包使用 exports 导出包或 opens 开放反射访问权限。
生成的 JRE 缺少必要模块检查 jlink--add-modules 参数是否包含所有依赖模块。

4.6 总结

构建模块化应用是 JDK 9 的核心能力,通过模块化系统实现强封装和显式依赖管理,显著提升了代码的安全性和可维护性。开发者应掌握模块定义、编译、打包及运行的全流程,并结合工具链(如 jdepsjlink)优化应用性能与兼容性。

相关文章:

2.4 构建模块化应用

第4章:构建模块化应用 模块化应用是 JDK 9 的核心特性之一,通过模块化系统(Project Jigsaw)实现代码的强封装和显式依赖管理。本章详细讲解如何从零构建一个模块化应用,包括模块定义、编译、打包、运行及调试。 4.1 模…...

DeepSeek:从入门到精通

在人工智能飞速发展的今天,DeepSeek作为一款备受瞩目的AI工具,正以其强大的功能和开源理念改变着我们的生活和工作方式。本文将带你深入了解DeepSeek,从基础入门到进阶应用,助你快速掌握这一前沿工具。 文末有详细资料可下载 文末…...

JAVA学习第二天

ArryList的构造方法和添加方法 01。构造方法的<>里面可以放数据类型 02. add&#xff08;&#xff09;可以直接在后面加入数据&#xff0c;也可以指定下标的插入元素。 ArrayList的常用方法 ArrayList存储对象 在Java中&#xff0c;System.out.println()可以打印基本数据…...

DevOps工具链概述

1. DevOps工具链概述 1.1 DevOps工具链的定义 DevOps工具链是支持DevOps实践的一系列工具的集合&#xff0c;这些工具覆盖了软件开发的整个生命周期&#xff0c;包括需求管理、开发、测试、部署和运维等各个环节。它旨在通过工具的集成和自动化&#xff0c;打破开发与运维之间…...

windows系统远程桌面连接ubuntu18.04

记录一下自己在配置过程中遇到的问题&#xff0c;记录遇到的两大坑&#xff1a; windows系统通过xrdp远程桌面连接ubuntu18.04的蓝屏问题。参考以下第一章解决。 同一局域网内网段不同的连接问题。参考以下第三章解决&#xff0c;前提是SSH可连。 1. 在ubuntu上安装xrdp 参考&…...

kafka动态监听主题

简单版本 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.ConsumerFactory; import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; import org.springframework.kafka.listener.Containe…...

Python虚拟环境管理工具 pyenv

情景 我现在在部署一个python 项目&#xff0c;需要用到Python 3.10。但是我本地已经有了一个3.12解释器&#xff0c;有没有一种方法&#xff0c;可以管理python 环境&#xff0c;还可以随意切换。怎么做&#xff1f; window 安装pyenv-win 使用 PowerShell&#xff08;以管…...

网络安全产品架构图 网络安全相关产品

一、信息安全产品分类 背景 美国将网络和信息安全产品分了9类&#xff1a;鉴别、访问控制、入侵检测、防火墙、公钥基础设施、恶意程序代码防护、漏洞扫描、取证、介质清理或擦除。中国公安部将网络和信息安全产品分了7类&#xff1a;操作系统安全、数据库安全、网络安全、病毒…...

C++ 实践扩展(Qt Creator 联动 Visual Studio 2022)

​ 这里我们将在 VS 上实现 QT 编程&#xff0c;实现如下&#xff1a; 一、Vs 2022 配置&#xff08;若已安装&#xff0c;可直接跳过&#xff09; 点击链接&#xff1a;​​​​​Visual Studio 2022 我们先去 Vs 官网下载&#xff0c;如下&#xff1a; 等待程序安装完成之…...

如何实现Deepseek的本地部署并集成本地知识库?

1、下载并配置Deepseek环境 https://blog.csdn.net/kxg6666/article/details/145593346?spm1001.2014.3001.5501 2、安装AnythingLLM AnythingLLM | The all-in-one AI application for everyone 如官网下载较慢&#xff0c;本文最后提供夸克离线下载链接。下载后默认安装…...

vue学习笔记8

Pinia基础使用 - 计数器案例 定义Store&#xff08;state action&#xff09; 组件使用Store getters实现 Pinia中的 getters 直接使用 computed函数 进行模拟, 组件中需要使用需要把 getters return出去 action异步实现 编写方式&#xff1a;异步action函数的写法和组件…...

【自学笔记】Vue基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Vue重点知识点总览一、Vue基础1. Vue简介2. MVVM设计思想3. 响应式数据绑定4. 组件化开发 二、Vue核心特性1. 虚拟DOM2. 模板语法3. 计算属性与监听属性 三、Vue高级…...

ETL的使用(sqoop):数据导入,导出

ETL ETL: 是数据抽取&#xff08;Extract&#xff09;、数据转换&#xff08;Transform&#xff09;和数据加载&#xff08;Load&#xff09;的整个过程 常用的ETL工具 sqoop 1.Apache Sqoop 是 Apache 软件基金会旗下的一个开源项目&#xff0c;旨在帮助用户高效地在 Hado…...

【核心特性】从鸭子类型到Go的io.Writer设计哲学

在编程语言的设计中&#xff0c;鸭子类型和接口设计是两种非常重要的理念。它们都强调了对象的行为和能力&#xff0c;而非其具体的类型或继承关系。Go 语言的io.Writer 接口是这种设计理念的典型代表&#xff0c;它通过简洁的接口定义&#xff0c;实现了强大的功能和灵活性。 …...

多模态模型详解

多模态模型是什么 多模态模型是一种能够处理和理解多种数据类型&#xff08;如文本、图像、音频、视频等&#xff09;的机器学习模型&#xff0c;通过融合不同模态的信息来提升任务的性能。其核心在于利用不同模态之间的互补性&#xff0c;增强模型的鲁棒性和准确性。 如何融合…...

Go 语言里中的堆与栈

在 Go 语言里&#xff0c;堆和栈是内存管理的两个重要概念&#xff0c;它们在多个方面存在明显差异&#xff1a; 1. 内存分配与回收方式 栈 分配&#xff1a;Go 语言中&#xff0c;栈内存主要用于存储函数的局部变量和调用信息。当一个函数被调用时&#xff0c;Go 会自动为其…...

八、OSG学习笔记-

前一章节&#xff1a; 七、OSG学习笔记-碰撞检测-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/145558132?spm1001.2014.3001.5501 一、了解OSG图元加载显示流程 本章节代码&#xff1a; OsgStudy/wids CuiQingCheng/OsgStudy - 码云 - 开源中国https:…...

本地部署【LLM-deepseek】大模型 ollama+deepseek/conda(python)+openwebui/docker+openwebui

通过ollama本地部署deepseek 总共两步 1.模型部署 2.[web页面] 参考官网 ollama:模型部署 https://ollama.com/ open-webui:web页面 https://github.com/open-webui/open-webui 设备参考 Mac M 芯片 windows未知 蒸馏模型版本:deepseek-r1:14b 运行情况macminim2 24256 本地…...

网络分析工具—WireShark的安装及使用

Wireshark 是一个广泛使用的网络协议分析工具&#xff0c;常被网络管理员、开发人员和安全专家用来捕获和分析网络数据包。它支持多种网络协议&#xff0c;能够帮助用户深入理解网络流量、诊断网络问题以及进行安全分析。 Wireshark 的主要功能 数据包捕获与分析&#xff1a; …...

MobaXterm的图形化界面支持:原理与分辨率问题解决

1. 概述 MobaXterm 是一款功能强大的远程访问工具&#xff0c;支持SSH、RDP、X11、VNC等多种协议&#xff0c;并内置了强大的图形界面支持&#xff0c;让用户能够在远程操作Linux/Unix系统时&#xff0c;享受到类似本地桌面的流畅体验。 与传统的SSH客户端不同&#xff0c;Mo…...

音频算法调试利器:用Android App实时绘制EQ/DRC曲线,告别Matlab依赖

移动端音频算法调试革命&#xff1a;Android实时EQ/DRC可视化工具开发实战 在音频算法开发领域&#xff0c;调试环节长期被桌面级工具垄断&#xff0c;工程师们不得不忍受开发板与工作站之间的频繁切换。这种工作模式不仅效率低下&#xff0c;更无法满足现代音频产品快速迭代的…...

基于本地大模型与Playwright的隐私优先求职自动化助手RedClaw实践

1. 项目概述&#xff1a;一个真正为你掌控的本地化求职AI助手在求职季&#xff0c;我们常常面临一个两难困境&#xff1a;一方面&#xff0c;海投简历耗时耗力&#xff0c;重复填写那些大同小异的在线申请表让人筋疲力尽&#xff1b;另一方面&#xff0c;市面上一些所谓的“自动…...

开源游戏串流革命:Sunshine如何重新定义家庭游戏共享体验

开源游戏串流革命&#xff1a;Sunshine如何重新定义家庭游戏共享体验 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 在游戏设备日益多样化的今天&#xff0c;你是否曾想过将高性能…...

5个高效方法:如何用AKShare处理金融数据去重,避免重复数据干扰分析

5个高效方法&#xff1a;如何用AKShare处理金融数据去重&#xff0c;避免重复数据干扰分析 【免费下载链接】akshare AKShare is an elegant and simple financial data interface library for Python, built for human beings! 开源财经数据接口库 项目地址: https://gitcod…...

QT 导出可执行 EXE 文件的方法

简介 本文分为两部分 第一部分导出exe文件&#xff0c;但是此文件需要很多其他文件支持&#xff0c;就是在一个文件夹里&#xff0c;里面不仅有exe&#xff0c;还有很多支持文件&#xff0c;使用的时候需要拷贝整个文件夹。 第二部分是单独导出exe&#xff0c;实际是在第一部…...

收藏 | 程序员小白也能掌握大模型开发,AI时代大有可为!

收藏 | 程序员小白也能掌握大模型开发&#xff0c;AI时代大有可为&#xff01; 本文针对非AI专业背景的程序员&#xff0c;介绍了如何参与大模型应用开发。内容涵盖大模型基础、提示词编写与提示工程技巧&#xff0c;以及使用OpenAI API和LangChain框架进行应用开发的关键步骤。…...

阴阳师自动化脚本终极指南:解放双手,轻松刷百鬼夜行

阴阳师自动化脚本终极指南&#xff1a;解放双手&#xff0c;轻松刷百鬼夜行 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 你是否厌倦了在阴阳师百鬼夜行中反复点击屏幕&#x…...

如何用3分钟搞定视频字幕提取?揭秘这款本地化硬字幕提取神器

如何用3分钟搞定视频字幕提取&#xff1f;揭秘这款本地化硬字幕提取神器 【免费下载链接】video-subtitle-extractor 视频硬字幕提取&#xff0c;生成srt文件。无需申请第三方API&#xff0c;本地实现文本识别。基于深度学习的视频字幕提取框架&#xff0c;包含字幕区域检测、字…...

企业微信代开发应用:CallBackUrl验证失败排查与CorpID加密升级实战

1. 企业微信代开发应用验证失败的典型场景 最近不少服务商朋友反馈&#xff0c;代开发应用在验证CallBackUrl时频繁失败。这个问题其实源于企业微信在2022年6月底进行的一次安全升级。当时官方发布公告称&#xff0c;为了提升账户安全性&#xff0c;所有新建的代开发应用都需要…...

用STM32CubeMX和HAL库驱动MG90S舵机:从PWM原理到代码实现的保姆级教程

用STM32CubeMX和HAL库驱动MG90S舵机&#xff1a;从PWM原理到代码实现的保姆级教程 第一次接触舵机控制时&#xff0c;我被那个小小的MG90S迷住了——它居然能精确地转动到指定角度&#xff01;但当我真正开始用STM32控制它时&#xff0c;才发现PWM参数配置的坑比想象中多得多。…...