\scoop`:
+
+```powershell
+# 查看 PowerShell 版本
+Get-Host | Select-Object Version
+# 标准安装
+irm get.scoop.sh | iex
+# 使用代理安装(若无法访问 GitHub)
+irm https://get.scoop.sh -Proxy '127.0.0.1:7890' | iex
+```
+
+------
+
+## 加速下载:Aria2 配置
+
+Scoop 支持 [aria2](https://github.com/aria2/aria2) 来实现多连接下载,提升下载速度。只需安装 aria2 即可:
+
+```powershell
+scoop install aria2
+scoop config aria2-warning-enabled false
+```
+
+### Aria2 配置项
+
+通过 `scoop config` 调整 aria2 设置:
+
+1. **aria2-enabled**(默认:true):启用/禁用 aria2。
+2. **aria2-warning-enabled**(默认:true):显示/隐藏 aria2 警告。
+3. **aria2-retry-wait**(默认:2):重试等待时间(秒)。
+4. **aria2-split**(默认:5):文件分段数。
+5. **aria2-max-connection-per-server**(默认:5):单服务器最大连接数。
+6. **aria2-min-split-size**(默认:5M):最小分段大小。
+7. **aria2-options**:自定义 aria2 参数。
+
+示例:
+
+```powershell
+scoop config aria2-split 10
+scoop config aria2-max-connection-per-server 8
+```
+
+------
+
+## 软件仓库推荐
+
+Scoop 的软件来源于“桶(bucket)”,分为官方和第三方仓库。
+
+### 官方仓库
+
+- **[Main](https://github.com/ScoopInstaller/Main)**:常用非 GUI 应用。
+- **[Extras](https://github.com/ScoopInstaller/Extras)**:不符合 Main 标准的应用。
+- **[Games](https://github.com/Calinou/scoop-games)**:开源/免费游戏及工具。
+- **[Nerd-fonts](https://github.com/matthewjberger/scoop-nerd-fonts)**:Nerd 字体。
+- **[Nirsoft](https://github.com/ScoopInstaller/Nirsoft)**:Nirsoft 工具集。
+- **[Sysinternals](https://github.com/niheaven/scoop-sysinternals)**:Sysinternals 套件。
+- **[Java](https://github.com/ScoopInstaller/Java)**:JDK/JRE 相关。
+- **[Nonportable](https://github.com/ScoopInstaller/Nonportable)**:不可移植应用。
+- **[PHP](https://github.com/ScoopInstaller/PHP)**:PHP 安装包。
+- **[Versions](https://github.com/ScoopInstaller/Versions)**:应用的替代版本。
+
+### 第三方仓库
+
+- **[scoopcn](https://github.com/scoopcn/scoopcn)**:国内应用为主。
+- **[dorado](https://github.com/chawyehsu/dorado)**:优质应用集合。
+- **[Cluttered-bucket](https://github.com/Paxxs/Cluttered-bucket)**:绿色软件及独立开发者应用。
+- **[scoopet](https://github.com/ivaquero/scoopet)**:学术研究相关工具。
+- **[scoop-zapps](https://github.com/kkzzhizhou/scoop-zapps)**:自动化更新仓库。
+- **[aki-apps](https://github.com/akirco/aki-apps)**:个人维护的 bucket。
+- **[siku](https://github.com/amorphobia/siku)**:个性化应用集合。
+- **[scoop-bear](https://github.com/AStupidBear/scoop-bear)**:包含 Navicat 等。
+- **[echo-scoop](https://github.com/echoiron/echo-scoop)**:包含 IDM 等。
+- **[abgo_bucket](https://github.com/abgox/abgo_bucket)**:包含 123pan 等。
+- **[diklios-scoop-bucket](https://github.com/diklios5768/diklios-scoop-bucket)**:包含 CooDesker 等。
+
+添加第三方仓库示例:
+
+```powershell
+scoop bucket add scoopcn https://github.com/scoopcn/scoopcn
+```
+
+------
+
+## 常用命令速查
+
+### 1. 获取帮助
+
+```powershell
+scoop help
+scoop help install
+```
+
+### 2. 安装应用
+
+- **当前用户安装**:
+
+```powershell
+scoop install nano
+```
+
+- **全局安装(需管理员权限)**:
+
+```powershell
+scoop install nano -g
+```
+
+- **高级选项**:
+
+```powershell
+scoop install git -g --no-cache --skip
+```
+
+### 3. 卸载应用
+
+- **卸载程序**:
+
+```powershell
+scoop uninstall nano
+```
+
+- **卸载并移除配置文件**:
+
+```powershell
+scoop uninstall nano -p
+```
+
+- **卸载全局程序**:
+
+```powershell
+scoop uninstall nano -g
+```
+
+### 4. 更新操作
+
+- **更新 Scoop 和 bucket**:
+
+```powershell
+scoop update
+```
+
+- **更新指定应用**:
+
+```powershell
+scoop update nano
+```
+
+- **更新所有**:
+
+```powershell
+scoop update *
+```
+
+### 5. 其他实用命令
+
+- **查看已安装应用**:
+
+```powershell
+scoop list
+```
+
+- **检查可更新应用**:
+
+```powershell
+scoop status
+```
+
+- **打开应用主页**:
+
+```powershell
+scoop home nano
+```
+
+- **管理 bucket**:
+
+```powershell
+scoop bucket known
+scoop bucket add extras
+scoop bucket list
+scoop bucket rm extras
+```
+
+- **清理旧版本和缓存**:
+
+```powershell
+scoop cleanup *
+scoop cache rm *
+```
+
+- 配置代理
+
+```powershell
+# 配置代理
+scoop config proxy '127.0.0.1:7890'
+# 移除代理
+scoop config rm proxy
+```
+
+------
+
+## 常见问题及解决
+
+### 问题:Inno Setup 错误
+
+错误信息:
+
+```
+Signature detected: Inno Setup Setup Data (6.3.0)
+This is not directly supported, but i'll try to unpack it as version 5602; Version detected: 6300
+Critical error: The setup files are corrupted. Please obtain a new copy of the program.
+```
+
+**解决方法**:
+
+安装 `innounp-unicode` 版本:
+
+```powershell
+scoop uninstall innounp
+scoop bucket add versions
+scoop install versions/innounp-unicode
+```
+
+------
+
+## 进阶学习
+
+想深入了解 Scoop?查看 [官方文档](https://github.com/ScoopInstaller/Scoop/wiki) 获取更多高级用法和技巧!
+
+------
+
+## 总结
+
+Scoop 是一个强大而优雅的工具,让 Windows 软件管理变得轻松高效。无论是快速安装开发工具,还是管理日常应用,Scoop 都能让你事半功倍。快来试试吧,打造属于你的高效环境!💻
\ No newline at end of file
diff --git a/src/programming/java/工具箱/SpringBoot打包体积优化.md b/src/programming/java/工具箱/SpringBoot打包体积优化.md
new file mode 100644
index 0000000..4f21359
--- /dev/null
+++ b/src/programming/java/工具箱/SpringBoot打包体积优化.md
@@ -0,0 +1,616 @@
+---
+icon: bi:arrows-expand
+date: 2025-05-13
+category:
+ - 实用工具
+ - JAVA
+ - SpringBoot
+ - JAR
+tag:
+ - JAR包瘦身
+title: SpringBoot打包体积优化.md
+---
+
+SpringBoot打包体积优化
+
+
+# Spring Boot JAR 瘦身与加密:构建安全高效的部署方案
+
+在 Spring Boot 应用程序部署过程中,我们常常面临两个主要挑战:
+
+1. **JAR 包体积过大**:Spring Boot 应用打包时会将所有依赖一起打包,导致最终 JAR 文件臃肿
+2. **代码安全性问题**:部署到客户环境或公开场合的 JAR 包可能被反编译,造成核心业务逻辑泄露
+
+为了解决这些问题,本文将介绍一套完整的解决方案,包括 JAR 包瘦身和 JAR 包加密两部分,以及配套的自定义类加载器,实现高效安全的
+Spring Boot 应用部署。
+
+## 整体方案设计
+
+该方案由两个主要项目组成:
+
+1. **spring-boot-jar-slim-encrypt**:用于将 Spring Boot 应用 JAR 包瘦身和加密
+2. **spring-boot-custom-classloader**:用于加载瘦身和加密后的 JAR 包
+
+### 工作流程
+
+```
+┌────────────────────┐
+│ 原始Spring Boot │
+│ JAR包 │
+└──────────┬─────────┘
+ │
+ ▼
+┌────────────────────┐ ┌────────────────────┐
+│ spring-boot-jar- │ │ │
+│ slim-encrypt工具 ├───►│ 提取依赖到libs目录 │
+└──────────┬─────────┘ └────────────────────┘
+ │
+ ▼
+┌────────────────────┐
+│ 瘦身后的JAR包 │
+└──────────┬─────────┘
+ │
+ ▼
+┌────────────────────┐
+│ XJar加密处理 │
+└──────────┬─────────┘
+ │
+ ▼
+┌────────────────────┐
+│ 加密后的JAR包 │
+│ (.xjar) │
+└──────────┬─────────┘
+ │
+ │ 部署
+ ▼
+┌─────────────────────────────────────────┐
+│ 运行时环境 │
+│ ┌─────────────────┐ ┌───────────────┐ │
+│ │ 加密JAR (.xjar) │ │ 提取的依赖库 │ │
+│ └────────┬────────┘ └───────┬───────┘ │
+│ │ │ │
+│ │ │ │
+│ ▼ ▼ │
+│ ┌─────────────────────────────────┐ │
+│ │ PlainTextClassLoader │ │
+│ │ (自定义类加载器) │ │
+│ └─────────────┬─────────────┬─────┘ │
+│ │ │ │
+│ ▼ ▼ │
+│ ┌─────────────────┐ ┌───────────────┐ │
+│ │ 解密JAR内容 │ │ 加载外部依赖 │ │
+│ └─────────────────┘ └───────────────┘ │
+│ │
+└─────────────────────────────────────────┘
+```
+
+1. 使用 spring-boot-jar-slim-encrypt 工具提取原始 JAR 包中的依赖
+2. 将依赖库单独存储在 libs 目录
+3. 对精简后的 JAR 包进行加密
+4. 使用自定义类加载器加载外部依赖和解密 JAR 包
+
+## 项目一:spring-boot-custom-classloader
+
+这是一个自定义类加载器项目,它实现了两种类加载器:
+
+### 1. JarClassLoader 接口
+
+```java
+package com.mangmang;
+
+import java.io.File;
+
+public interface JarClassLoader {
+ String JAR_EXTENSION = ".jar";
+
+ /**
+ * 从指定目录加载所有JAR文件
+ *
+ * @param jarDir 包含要加载的JAR文件的目录路径
+ * @throws IllegalArgumentException 如果jarDir为null或不存在
+ */
+ default void loadJar(String jarDir) {
+ if (jarDir == null || jarDir.trim().isEmpty()) {
+ throw new IllegalArgumentException("JAR目录路径不能为空");
+ }
+
+ File directory = new File(jarDir);
+ if (!directory.exists() || !directory.isDirectory()) {
+ throw new IllegalArgumentException("指定路径不是有效目录: " + jarDir);
+ }
+
+ File[] jarFiles = directory.listFiles(this::isJarFile);
+ if (jarFiles == null) {
+ return;
+ }
+
+ for (File jarFile : jarFiles) {
+ System.out.println("加载 》" + jarFile.getName());
+ scanJarFile(jarFile);
+ }
+ }
+
+ /**
+ * 递归扫描文件或目录以查找JAR文件
+ *
+ * @param file 要扫描的文件或目录
+ * @throws IllegalArgumentException 如果file为null
+ */
+ default void scanJarFile(File file) {
+ if (file == null) {
+ throw new IllegalArgumentException("文件不能为null");
+ }
+
+ if (!file.exists()) {
+ return;
+ }
+
+ if (isJarFile(file)) {
+ addJARFile(file);
+ } else if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ if (files != null) {
+ for (File f : files) {
+ scanJarFile(f);
+ }
+ }
+ }
+ }
+
+ /**
+ * 检查文件是否为JAR文件
+ */
+ default boolean isJarFile(File file) {
+ return file.isFile() && file.getName().endsWith(JAR_EXTENSION);
+ }
+
+ /**
+ * 将JAR文件添加到类加载器
+ *
+ * @param jar 要添加的JAR文件
+ * @throws IllegalArgumentException 如果jar为null或不是有效的JAR文件
+ */
+ void addJARFile(File jar);
+}
+
+```
+
+这是一个接口,定义了 JAR 文件加载的核心方法:
+
+- `loadJar(String jarDir)`: 从指定目录加载所有 JAR 文件
+- `scanJarFile(File file)`: 递归扫描文件或目录查找 JAR 文件
+- `isJarFile(File file)`: 检查文件是否为 JAR 文件
+- `addJARFile(File jar)`: 将 JAR 文件添加到类加载器
+
+### 2. PlainTextClassLoader 实现
+
+```java
+package com.mangmang;
+
+import org.springframework.boot.context.event.ApplicationStartingEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.lang.NonNull;
+
+import java.io.File;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 明文类加载器
+ *
+ * 该类实现了自定义类加载器接口和Spring应用启动事件监听器接口。
+ * 主要功能是在应用启动时,从JVM启动参数中查找指定路径的JAR文件并加载。
+ * 通过反射机制将JAR文件动态添加到当前线程的类加载器中,实现运行时加载额外的类库。
+ *
+ *
+ * 使用方法:
+ * 1. 在JVM启动参数中添加 -Dexternal.jars.path=你的JAR文件目录路径
+ * 2. 系统将自动加载该目录下所有的JAR文件
+ *
+ *
+ * 示例:
+ * java -Dexternal.jars.path.path=/path/to/jars -jar your-application.jar
+ *
+ */
+public class PlainTextClassLoader implements JarClassLoader, ApplicationListener {
+
+ private final String findPath = "external.jars.path"; // 查找路径的键名
+ private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // 获取当前线程的类加载器
+ private final List jarFiles = new ArrayList<>(); // 存储已加载的JAR文件列表
+
+ /**
+ * 构造函数
+ *
+ * 在初始化时执行以下操作:
+ * 1. 设置当前线程的类加载器
+ * 2. 输出启动日志信息
+ * 3. 从JVM启动参数中检索包含"external.jars.path.path"的参数
+ * 4. 提取路径值并调用loadJar方法加载指定目录下的JAR文件
+ *
+ */
+ public PlainTextClassLoader() {
+ // 设置当前线程的类加载器
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ // 打印启动信息
+ System.out.println("启动自定义明文类加载器");
+
+ // 查找并加载外部JAR文件
+ loadExternalJarsFromSystemProperties();
+ }
+
+ /**
+ * 从系统属性中查找并加载外部JAR文件
+ */
+ private void loadExternalJarsFromSystemProperties() {
+ List inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
+
+ // 查找包含指定路径参数的启动参数
+ inputArguments.stream()
+ .filter(arg -> arg.contains(findPath))
+ .map(this::extractPathFromArgument)
+ .filter(Objects::nonNull)
+ .forEach(this::loadJar);
+ }
+
+ /**
+ * 从JVM参数中提取路径值
+ *
+ * @param argument JVM启动参数
+ * @return 提取的路径值,如果提取失败则返回null
+ */
+ private String extractPathFromArgument(String argument) {
+ String prefix = "-D" + findPath + "=";
+ if (argument.startsWith(prefix)) {
+ String path = argument.replace(prefix, "");
+ if (!path.isEmpty()) {
+ return path;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 处理应用程序启动事件
+ *
+ * 当Spring应用启动时会触发此方法。
+ * 目前该方法为空实现,可以在此添加应用启动时需要执行的代码。
+ *
+ *
+ * @param event Spring应用启动事件对象
+ */
+
+ @Override
+ public void onApplicationEvent(@NonNull ApplicationStartingEvent event) {
+ // 应用程序启动事件的处理方法,目前为空
+ }
+
+ /**
+ * 将JAR文件添加到类加载器
+ *
+ * 通过反射机制调用URLClassLoader的addURL方法,将指定的JAR文件URL添加到当前类加载器。
+ * 添加成功后,JAR文件中的类可以被当前JVM加载和使用。
+ * 同时将已加载的JAR文件记录到jarFiles列表中。
+ *
+ *
+ * @param jar 要添加到类加载器的JAR文件对象
+ * @throws RuntimeException 如果添加过程中发生任何异常,将抛出RuntimeException
+ */
+ @Override
+ public void addJARFile(File jar) {
+ if (jar == null) {
+ throw new IllegalArgumentException("JAR文件不能为null");
+ }
+
+ try {
+ addUrlToClassLoader(jar);
+ jarFiles.add(jar);
+ System.out.println(jarFiles);
+ } catch (Exception e) {
+ throw new RuntimeException("添加JAR文件到类加载器失败: " + jar.getName(), e);
+ }
+ }
+
+ /**
+ * 通过反射将JAR文件URL添加到类加载器
+ *
+ * @param jar 要添加的JAR文件
+ * @throws Exception 如果反射操作失败
+ */
+ private void addUrlToClassLoader(File jar) throws Exception {
+ Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
+ if (!addUrlMethod.isAccessible()) {
+ addUrlMethod.setAccessible(true);
+ }
+ URL jarUrl = jar.toURI().toURL();
+ addUrlMethod.invoke(classLoader, jarUrl);
+ }
+```
+
+这是一个明文类加载器,实现了 `JarClassLoader` 接口和 Spring 的 `ApplicationListener` 接口,用于在
+Spring Boot 应用启动时加载外部 JAR 文件:
+
+主要特点:
+
+- 在 Spring Boot 应用启动时自动执行
+- 通过 JVM 参数 `-Dexternal.jars.path=你的JAR文件目录路径` 指定外部 JAR 文件目录
+- 使用反射机制将 JAR 文件 URL 添加到当前线程的类加载器中
+
+使用示例:
+
+```bash
+java -Dexternal.jars.path=/path/to/jars -jar your-application.jar
+```
+
+## 项目二:spring-boot-jar-slim-encrypt
+
+这个工具用于压缩和加密 Spring Boot JAR 文件,主要包含以下两个核心类:
+
+### 1. JarUtil 工具类
+
+```java
+// 路径:spring-boot-jar-slim-encrypt/src/main/java/com/mangmang/JarUtil.java
+package com.sunri;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.io.FileUtil;
+import io.xjar.XCryptos;
+import io.xjar.XEncryption;
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.commons.compress.utils.Sets;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+public class JarUtil {
+ /**
+ * 表示UTF-8字符编码的常量。
+ * 该变量用于在各种文件操作中强制使用UTF-8编码,
+ * 确保在整个应用程序中一致地处理文本数据。
+ */
+ private static final String UTF_8 = "UTF-8";
+ /**
+ * 常量BOOT_INF_LIB表示JAR文件中通常存储依赖库的默认目录路径。
+ * 该路径主要用于在压缩或排除等操作中识别和处理库文件。
+ */
+ private static final String BOOT_INF_LIB = "BOOT-INF/lib";
+ /**
+ * 用于标识JAR(Java归档)文件的文件扩展名。
+ * 该常量表示JAR文件的标准扩展名,通常用于
+ * 文件过滤、命名或在目录或归档中识别JAR文件的操作。
+ */
+ private static final String JAR_EXTENSION = ".jar";
+ /**
+ * 定义在管理JAR过程中生成的需求文件的后缀,
+ * 特别是在处理依赖项或排除项时使用。
+ * 该字符串用作特定的文件名模式,用于保存与特定服务
+ * 相关的排除依赖项或其他需求的列表。
+ * 默认值为"-requirements.txt"。
+ */
+ private static final String REQUIREMENTS_SUFFIX = "-requirements.txt";
+ /**
+ * 预定义的、不可修改的特定jar文件名集合,被视为
+ * "安全"或"始终包含"的文件。这些jar文件通常在
+ * 处理或压缩操作中免于排除过滤。
+ * 该集合包含以下jar标识符:
+ * - "spring"
+ * - "logback-core"
+ * - "tomcat"
+ * 该变量用于根据jar文件名决定是否包含特定jar文件的操作中。
+ * 它作为应用程序关键或必要jar的白名单。
+ */
+ private static final Set WHITE_LIST_JARS = Sets.newHashSet("spring", "logback-core", "tomcat");
+
+ /**
+ * 通过排除和包含指定的条目来压缩给定的源JAR文件,并将结果写入目标JAR文件。
+ * 它处理源JAR的条目,应用排除和包含规则,还可以将某些条目提取到指定的目录中。
+ * 在此过程中创建一个临时文件,成功完成后将其重命名为目标JAR文件。
+ *
+ * @param serviceName 正在处理的服务名称,主要用于日志记录和创建其他相关文件。
+ * @param sourceJar 要压缩的源JAR文件。
+ * @param includes 指定应保留哪些条目的包含模式集合。可能会自动添加额外的默认包含项。
+ * @param exclusions 指定应排除哪些条目的排除模式集合。
+ * @param targetJar 将写入压缩JAR的文件。
+ * @param libDir 某些被排除的条目可能被提取到的目录(如适用)。
+ */
+ public static void compress(String serviceName, File sourceJar, Set includes, Set exclusions, File targetJar, String libDir) {
+ includes.addAll(WHITE_LIST_JARS);
+ File tempJar = new File(targetJar.getAbsolutePath() + ".tmp");
+ Set excludedJars = new HashSet<>();
+
+ if (processJarEntries(sourceJar, tempJar, includes, exclusions, libDir, excludedJars)) {
+ finalizeCompression(serviceName, targetJar, tempJar, excludedJars, libDir);
+ } else {
+ boolean delete = tempJar.delete();
+ System.out.println("删除临时文件:{" + delete + "}");
+ }
+ }
+
+ /**
+ * 处理源JAR文件中的条目以生成临时JAR文件,
+ * 同时根据包含和排除规则过滤条目。如果需要,
+ * 还会将指定的JAR条目提取到库目录中。
+ *
+ * @param sourceJar 要处理的源JAR文件
+ * @param tempJar
+```
+
+这个工具类提供了两个主要功能:
+
+#### JAR 包压缩功能
+
+`compress` 方法实现了 JAR 瘦身功能:
+
+- 根据包含列表和排除列表过滤 JAR 中的依赖
+- 将被排除的依赖提取到指定的库目录
+- 生成一个记录排除依赖的需求文件
+- 创建一个只包含必要依赖的精简 JAR 文件
+
+#### JAR 包加密功能
+
+`encrypt` 方法利用 XJar 库实现了 JAR 加密:
+
+- 支持指定加密密码
+- 通过包含和排除模式选择性地加密 JAR 中的内容
+- 生成加密后的 XJar 文件
+
+### 2. SpringBootJarSlimEncryptApplication 主应用
+
+```java
+// 路径:spring-boot-jar-slim-encrypt/src/main/java/com/mangmang/SpringBootJarSlimEncryptApplication.java
+```
+
+这是工具的主应用类,提供了完整的命令行接口来处理 JAR 文件的压缩和加密:
+
+主要功能:
+
+- 通过配置常量定义输入/输出目录、加密设置等
+- 支持从 XML 配置文件加载要包含和排除的依赖项
+- 批量处理多个 JAR 文件
+- 支持通过系统属性覆盖默认配置
+
+主要配置参数:
+
+- `xml.dir`: 依赖项 XML 文件目录(默认: `./config/xml/`)
+- `raw.dir`: 原始 JAR 文件目录(默认: `./config/rawJars/`)
+- `compress.dir`: 压缩后 JAR 文件目录(默认: `./config/compressJars/`)
+- `libs.dir`: 提取的库文件目录(默认: `./config/libs/`)
+- `xjar.dir`: 加密后的 XJar 文件目录(默认: `./config/xJars/`)
+- `compress.enable`: 是否启用压缩功能(默认: `true`)
+
+## 使用步骤
+
+### 步骤 1: 集成自定义类加载器
+
+在你的 Spring Boot 项目中添加自定义类加载器依赖:
+
+```xml
+
+
+ com.mangmang
+ spring-boot-custom-classloader
+ 1.0.0
+
+```
+
+### 步骤 2: 构建 Spring Boot 应用
+
+正常构建你的 Spring Boot 应用:
+
+```bash
+mvn clean package
+```
+
+### 步骤 3: 配置依赖排除和包含规则
+
+创建两个 XML 文件以定义要排除和包含的依赖项:
+
+**exclusions.xml**(要排除的依赖):
+
+```xml
+
+
+
+ spring-boot-starter-web
+ 2.7.0
+
+
+
+```
+
+**includes.xml**(要保留的依赖):
+
+```xml
+
+
+
+ spring-boot-custom-classloader
+
+
+
+```
+
+### 步骤 4: 执行 JAR 瘦身和加密工具
+
+将你的 Spring Boot JAR 文件放入 `./config/rawJars/` 目录,然后运行瘦身加密工具:
+
+```bash
+java -jar spring-boot-jar-slim-encrypt.jar
+```
+
+你可以通过系统属性覆盖默认配置:
+
+```bash
+java -Dcompress.enable=true -Dlibs.dir=/custom/libs/path -jar spring-boot-jar-slim-encrypt.jar
+```
+
+### 步骤 5: 部署和运行
+
+部署加密后的 JAR 文件和提取的库文件:
+
+```bash
+java -Dexternal.jars.path=/path/to/libs -jar your-application.xjar
+```
+
+## 技术原理解析
+
+### JAR 瘦身原理
+
+1. 扫描 Spring Boot JAR 中的 `BOOT-INF/lib` 目录
+2. 根据配置的排除和包含规则过滤依赖
+3. 将被排除的依赖提取到外部目录
+4. 创建一个不包含被排除依赖的新 JAR 文件
+
+### JAR 加密原理
+
+1. 使用 XJar 库实现 JAR 文件内容的加密
+2. 只加密指定的文件模式(如 Java 类文件、配置文件等)
+3. 避免加密某些需要保持明文的资源
+
+### 自定义类加载器原理
+
+1. 在 Spring Boot 应用启动时初始化自定义类加载器
+2. 扫描指定目录下的 JAR 文件
+3. 使用反射机制将 JAR 文件 URL 添加到当前类加载器
+
+## 方案优势
+
+1. **减小 JAR 体积**:将大型依赖库外置,显著减小主 JAR 文件体积
+2. **提高安全性**:通过加密保护核心业务逻辑和敏感配置
+3. **灵活配置**:支持通过 XML 配置和系统属性灵活控制瘦身和加密过程
+4. **无缝集成**:与 Spring Boot 应用无缝集成,无需修改应用代码
+
+## 注意事项
+
+1. 确保加密密码安全保存,丢失密码将导致无法运行加密的 JAR
+2. 测试瘦身后的应用,确保所有需要的依赖都能正确加载
+3. 部署时必须将提取的依赖库和加密后的 JAR 一起部署
+4. 启动应用时必须指定外部库路径参数
+
+## 结论
+
+通过结合 JAR 瘦身、JAR 加密和自定义类加载器,我们成功构建了一套完整的 Spring Boot 应用优化和保护方案。这不仅有效减小了部署包的体积,还提高了应用的安全性,为企业级
+Spring Boot 应用的部署提供了一种实用的解决方案。
+
+在实际应用中,可以根据具体需求调整配置参数,以达到最佳的平衡点。例如,可以根据应用规模和安全需求调整要排除的依赖和加密的文件模式。
+
+这套工具实现了将原本臃肿的 Spring Boot 应用拆分为核心加密 JAR 和外部依赖库的方案,使得应用部署更加灵活,也为应用分发和更新提供了更多可能性。
+
+------
+
+*注:本方案适用于需要保护核心业务逻辑或减小部署包体积的 Spring Boot
+应用。对于简单应用或开源项目,可能不必使用这么复杂的方案。*
\ No newline at end of file
diff --git a/src/programming/java/工具箱/WebSocket和HTTP关系.md b/src/programming/java/工具箱/WebSocket和HTTP关系.md
index 3f7c3e0..5de9ca1 100644
--- a/src/programming/java/工具箱/WebSocket和HTTP关系.md
+++ b/src/programming/java/工具箱/WebSocket和HTTP关系.md
@@ -7,6 +7,7 @@ category:
tag:
- websocket
- http
+title: WebSocket和HTTP关系
---
# WebSocket和HTTP关系
@@ -14,7 +15,7 @@ tag:
## 1. WebSocket简介
WebSocket 是 HTML5 提供的一种在单个 TCP 连接上进行全双工通讯的协议。它使客户端和服务器之间的数据交换变得更加简单高效,并允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需完成一次握手,便可创建持久性的连接,实现双向数据传输。
-
+
## 2. WebSocket与HTTP的关系
### 2.1 协议转换过程
diff --git a/src/programming/java/工具箱/XJar.md b/src/programming/java/工具箱/XJar.md
new file mode 100644
index 0000000..7ec0a63
--- /dev/null
+++ b/src/programming/java/工具箱/XJar.md
@@ -0,0 +1,230 @@
+---
+icon: bi:arrows-expand
+date: 2025-05-13
+category:
+ - JAVA
+ - 加密
+tag:
+ - xjar
+title: XJar
+---
+
+XJar:保护您的Java应用程序免受反编译和源码泄露
+
+# XJar:保护您的Java应用程序免受反编译和源码泄露
+
+介绍一个强大且实用的工具——**XJar**。它专为Spring Boot JAR和原生JAR提供安全加密运行支持,能够有效防止源码泄露和反编译的风险。无论你是想保护个人项目还是企业级应用,XJar都能为你提供一个简单而高效的解决方案。
+
+GitHub: https://github.com/core-lib/xjar
+
+## 什么是XJar?
+
+XJar是一个开源工具,通过对JAR包内的资源进行加密,并结合扩展的ClassLoader,构建了一套程序加密启动和动态解密运行的机制。它特别适合Spring Boot项目,同时也支持原生JAR,旨在帮助开发者保护Java应用程序的安全性。
+
+## 功能特性
+
+XJar提供了以下核心功能,让它在加密工具中脱颖而出:
+
+- **无代码侵入**:无需修改源代码,只需对编译好的JAR包进行加密即可。
+- **完全内存解密**:资源在运行时动态解密,减少源码或字节码泄露的风险。
+- **支持所有JDK内置加解密算法**:灵活选择适合你的加密算法。
+- **资源加密灵活性**:支持选择需要加密的字节码或其他资源文件。
+- **Maven插件支持**:集成到构建流程,加密更便捷。
+- **Go启动器**:动态生成Go语言启动器,保护密码不泄露。
+
+## 环境依赖
+
+- **JDK版本**:1.7及以上
+
+## 使用步骤
+
+下面我将详细介绍如何使用XJar加密你的JAR包,步骤清晰易懂。
+
+### 1. 添加依赖
+
+首先,在你的Maven项目中添加XJar依赖,并配置jitpack.io仓库:
+
+```xml
+
+
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+
+
+
+ com.github.core-lib
+ xjar
+ 4.0.2
+
+
+
+```
+
+> **小贴士**:如果只是用JUnit测试加密过程,可以将``设置为`test`。
+
+### 2. 加密源码
+
+使用XJar提供的`XCryptos.encryption()`方法对JAR包进行加密:
+
+```java
+XCryptos.encryption()
+ .from("/path/to/read/plaintext.jar") // 待加密JAR包路径
+ .use("io.xjar") // 加密密码
+ .include("/io/xjar/**/*.class") // 需要加密的字节码
+ .include("/mapper/**/*Mapper.xml") // 需要加密的资源文件
+ .exclude("/static/**/*") // 排除静态文件
+ .exclude("/conf/*") // 排除配置文件
+ .to("/path/to/save/encrypted.jar"); // 输出加密后的JAR包
+```
+
+- `include`和`exclude`支持ANT表达式或正则表达式,灵活控制加密范围。
+- 当两者同时使用时,加密范围为`include`内排除`exclude`后的资源。
+
+### 3. 编译脚本
+
+加密完成后,XJar会在输出目录生成一个`xjar.go`文件。这是Go语言编写的启动器源码,需要编译为可执行文件:
+
+- **Windows**:编译后生成`xjar.exe`
+- **Linux**:编译后生成`xjar`
+
+编译需要Go环境,但运行时无需Go支持。注意:启动器带有防篡改校验,无法通用。
+
+### 4. 启动运行
+
+使用编译好的启动器运行加密后的JAR包:
+
+```shell
+./xjar java -Xms256m -Xmx1024m -jar /path/to/encrypted.jar
+```
+
+- 启动器需放在Java命令之前。
+- 仅支持`-jar`方式启动,不支持`-cp`或`-classpath`。
+- 使用`nohup`时,需写为:`nohup ./xjar java -jar /path/to/encrypted.jar`。
+
+## 注意事项
+
+在使用XJar时,以下问题可能影响你的体验,我整理了解决方案供参考:
+
+### 1. Spring Boot Maven插件兼容性
+
+XJar不支持`spring-boot-maven-plugin`的`executable = true`和`embeddedLaunchScript`配置,需删除:
+
+```xml
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+```
+
+### 2. Spring Boot + JPA(Hibernate)报错
+
+若使用Hibernate,启动可能报错。解决方法:
+
+1. 克隆[XJar-Agent-Hibernate](https://github.com/core-lib/xjar-agent-hibernate),编译生成`xjar-agent-hibernate-${version}.jar`。
+
+2. 启动命令添加代理:
+
+ ```shell
+ ./xjar java -javaagent:xjar-agent-hibernate-${version}.jar -jar your-app.jar
+ ```
+
+### 3. 静态文件加载问题
+
+加密静态文件可能导致浏览器加载失败,建议排除加密:
+
+```java
+.exclude("/static/**/*")
+.exclude("/META-INF/resources/**/*")
+```
+
+### 4. JDK 9+模块化问题
+
+在JDK 9及以上版本,需添加参数:
+
+```shell
+./xjar java --add-opens java.base/jdk.internal.loader=ALL-UNNAMED -jar /path/to/encrypted.jar
+```
+
+### 5. 阿里云Maven镜像问题
+
+使用阿里云镜像时,需在`mirrorOf`中排除jitpack.io:
+
+```xml
+
+ alimaven
+ central,!jitpack.io
+ http://maven.aliyun.com/nexus/content/repositories/central/
+
+```
+
+## 插件集成
+
+XJar提供了[xjar-maven-plugin](https://github.com/core-lib/xjar-maven-plugin),可自动完成加密过程。
+
+### 配置示例
+
+```xml
+
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+
+
+
+ com.github.core-lib
+ xjar-maven-plugin
+ 4.0.2
+
+
+
+ build
+
+ package
+
+ io.xjar
+
+
+
+
+
+
+
+```
+
+### 执行方式
+
+- **自动构建**:`mvn clean package -Dxjar.password=io.xjar`
+- **手动执行**:`mvn xjar:build -Dxjar.password=io.xjar`
+
+> **强烈建议**:不要在`pom.xml`中写死密码,通过命令行传递更安全!
+
+## 参数说明
+
+以下是`xjar-maven-plugin`的主要参数:
+
+| 参数名称 | 命令参数 | 参数说明 | 参数类型 | 缺省值 |
+| --------- | ---------------- | ------------ | -------- | -------------------------- |
+| password | -Dxjar.password | 密码字符串 | String | 必须 |
+| algorithm | -Dxjar.algorithm | 加密算法名称 | String | AES/CBC/PKCS5Padding |
+| keySize | -Dxjar.keySize | 密钥长度 | int | 128 |
+| ivSize | -Dxjar.ivSize | 密钥向量长度 | int | 128 |
+| sourceDir | -Dxjar.sourceDir | 源JAR目录 | File | ${project.build.directory} |
+| targetDir | -Dxjar.targetDir | 目标JAR目录 | File | ${project.build.directory} |
+
+更多详情见:[xjar-maven-plugin](https://github.com/core-lib/xjar-maven-plugin)。
+
+## 结尾
+
+XJar以其无侵入性、灵活性和高效性,成为保护Java应用的绝佳选择。无论是个人项目还是商业产品,它都能帮你轻松加密JAR包,确保代码安全。赶快试试吧!
\ No newline at end of file