当前位置: 首页 > 软件库 > 开发工具 > Java开发工具 >

slot-maven-plugin

可插件化拓展改造器
授权协议 Apache
开发语言 Java
所属分类 开发工具、 Java开发工具
软件类型 开源软件
地区 国产
投 递 者 杜禄
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Slot 

Spring Boot 可插件化拓展改造器,让 Spring-Boot 应用支持加载外部 jar 包,实现插件化拓展。

GitHub: https://github.com/core-lib/slot-maven-plugin

Slot: 在计算机行业指的就是周边元件扩展插槽。

问题描述

Spring-Boot 项目打包后是一个FatJar 即把所有依赖的第三方jar也打包进自身的jar中,运行时 classpath 包括 FatJar 中的 BOOT-INF/classes 目录和 BOOT-INF/lib 目录下的所有jar。

那么问题是要想加载外部化 jar 就只能打包期间把 jar 依赖进去,无法实现可插拔式插件化拓展。

Slot 就是一个可以将 Spring-Boot 项目升级为可支持加载外部 jar 的 Maven 插件。

原理说明

一个 Spring-Boot JAR 启动的流程可以分为以下几步:

  1. 通过 java -jar spring-boot-app.jar args... 命令启动

  2. JVM 读取该 jar 的 META-INF/MANIFEST.MF 文件中的 Main-Class,在 Spring-Boot JAR 中这个值通常为 org.springframework.boot.loader.JarLauncher

  3. JVM 调用该类的 main 方法,传入参数即上述命令中参数

  4. JarLauncher 构建 ClassLoader 并反射调用 META-INF/MANIFEST.MF 中的 Start-Class 类的 main 方法,通常为项目中的 Application 类

  5. Application 类的 main 方法调用 SpringApplication.run(Application.class, args); 以最终启动应用

Slot 的核心原理是:

  1. 拓展 org.springframework.boot.loader.JarLauncher 实现根据启动命令参数读取外部 jar 包并且加入至 classpath 中

  2. 修改 META-INF/MANIFEST.MF 中的 Main-Class 为拓展的 JarLauncher

环境依赖

  1. JDK 1.7 +

  2. Spring-Boot

使用说明

<project>
    <!-- 设置 jitpack.io 插件仓库 -->
    <pluginRepositories>
        <pluginRepository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </pluginRepository>
    </pluginRepositories>
    <!-- 添加 Slot Maven 插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>com.github.core-lib</groupId>
                <artifactId>slot-maven-plugin</artifactId>
                <version>LATEST_VERSION</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>transform</goal>
                        </goals>
                        <phase>package</phase>
                        <configuration>
                            <!-- optional
                            <sourceDir/>
                            <sourceJar/>
                            <targetDir/>
                            <targetJar/>
                            -->
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

参数说明

参数名称 命令参数名称 参数说明 参数类型 缺省值 示例值
sourceDir -Dslot.sourceDir 源jar所在目录 File ${project.build.directory} 文件目录
sourceJar -Dslot.sourceJar 源jar名称 String ${project.build.finalName}.jar 文件名称
targetDir -Dslot.targetDir 目标jar存放目录 File ${project.build.directory} 文件目录
targetJar -Dslot.targetJar 目标jar名称 String ${project.build.finalName}.slot 文件名称

插件的默认执行阶段是 package , 当然也可以通过使用以下命令来单独执行。

mvn slot:transform

mvn slot:transform -Dslot.targetJar=your-spring-boot-app-slot.jar

默认情况下,通过 slot 升级后的 jar 名称为 ${project.build.finalName}-slot.jar ,可以通过插件配置或命令参数修改。

注意事项

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <!-- 需要将executable和embeddedLaunchScript参数删除,目前还不能支持对该模式Jar的升级!
    <configuration>
        <executable>true</executable>
        <embeddedLaunchScript>...</embeddedLaunchScript>
    </configuration>
    -->
</plugin>

启动应用

Slot 支持使用两个参数来指定要加载的外部 jar 包:

  1. --slot.root 即外部 jar 的根路径,缺省情况下为 Spring-Boot JAR 包的目录。

  2. --slot.path 即外部 jar 的路径,支持设置多个,支持 ANT 表达式风格。

java -jar spring-boot-app-slot.jar --slot.root=/absolute/root/ --slot.path=foo.jar  --slot.path=bar.jar

java -jar spring-boot-app-slot.jar --slot.path=/relative/path/to/plugin.jar

java -jar spring-boot-app-slot.jar --slot.path=/relative/path/to/**.jar

ANT 表达式通配符说明

通配符 含义 示例
** 任意个字符及目录 /plugins/**.jar 即 /plugins 目录及子目录的所有 .jar 后缀的文件
* 任意个字符 /plugins/*.jar 即 /plugins 目录的所有 .jar 后缀的文件
? 单个字符 ???.jar 即当前目录所有名称为三个任意字符及以 .jar 为后缀的文件

通配符可以随意组合使用! 例如 /plugins/**/plugin-*-v???.jar

使用技巧

由于通过 Slot 加载后的外部 jar 实际上和 Spring-Boot JAR 中的 jar 处于同一个 ClassLoader 所以外部插件和母体应用之间是一个平级的关系, 外部插件可以引用母体应用中的 class 同样母体应用也可以引用外部插件的 class。

由于外部插件项目或模块通常也会依赖另外的第三方jar,所以外部插件与母体应用集成运行时也需要把另外的第三方jar通过--slot.path参数加载进来。 推荐使用 maven-dependency-plugin 在打包时将需要用到的第三方jar拷贝到指定目录,最后通过ANT表达式方式一起加载运行。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <includeScope>runtime</includeScope>
                <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

或者使用 maven-shade-plugin 插件把相关的第三方jar资源通通打包进一个。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.1.1</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                ...
            </configuration>
        </execution>
    </executions>
</plugin>

另外需要注意的是,当母体应用和外部插件有相同的第三方依赖时,推荐让外部插件模块以 <scope>provided</scope> 的方式依赖之。

下面是作者想到的一些插件化拓展的方案:

  1. IoC方式:母体应用声明接口,外部插件实现接口并且通过 @Component @Service 或其他注解让Spring 容器管理, 母体应用通过 @Resource @Autowired 来注入。

  2. SPI方式:母体应用声明接口,外部插件实现接口并且配置于 META-INF/services/ 下,母体应用通过 ServiceLoader 加载接口的实现类。

  3. AOP方式:外部插件通过 Spring Aspect 技术实现对母体应用的切面拦截。

版本记录

  • 1.0.1 bug 修复

  • 1.0.0 第一个正式版发布

协议声明

Apache-2.0

联系作者

QQ 646742615 不会钓鱼的兔子

  • 一、vue中的插槽 1.1 vue中插槽要解决的问题 slot 插槽 ,是用在组件中,向组件分发内容。它的内容可以包含任何模板代码,包括HTML。它会解决下面的问题: <template> <div> <p>buttonTest</p> <my-button> <!-- 处于自定义标签中的内容,如何呈现 --> button </my-butto

  • 在使用Maven GPG Plugin之前,首先需要确认命令行下的gpg是可用的,然后如下所示配置POM。 <project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <arti

  • <!-- 编译插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1

  • 最近开发的产品,我们是有四五个maven模块,开发阶段一直是在eclipse中运行的,然后快发版的时候,需要把这些项目打成jar包,通过命令去启动,那首先就得把这些模块项目打包,或者拷贝一些资源文件等等。 1.maven打包,首先在pom文件中加上build属性,和dependencies是同级的: <build> <!--打包出来的文件名,可以不填写,有默认值--> <finalName>T

  • 可用的Goals Goal 描述 android:apk 创建apk文件。默认使用debug密钥对Apk签名。 如需修改可以修改配置参数为<sign><debug>false</debug></sign> android:apklib 创建apklib文件。apklib文件并不会被部署。 android:deploy 部署编译好或指定的apk文件到一个连接的设备上。在运行mvn integrati

  • 整合spark3.3.x和hive2.1.1-cdh6.3.2碰到个问题,就是spark官方支持的hive是2.3.x,但是cdh中的hive确是2.1.x的,项目中又计划用spark-thrift-server,导致编译过程中有部分报错。其中OperationLog这个类在hive2.3中新增加了几个方法,导致编译报错。这个时候有两种解决办法: 修改spark源码,注释掉调用OperationL

  • 插件 plugin description issues org.apache.maven.plugins maven-antrun-plugin 运行ant任务,甚至可以在pom中嵌入ant脚本 org.apache.maven.plugins maven-clean-plugin 删除构建时在项目target目录中生成的文件 org.apache.maven.plugins maven-che

  • maven是个项目管理工具,如果我们不告诉它我们的代码要使用什么样的jdk版本编译的话,它就会用maven-compiler-plugin默认的jdk版本来进行处理,这样就容易出现版本不匹配,以至于可能导致编译不通过的问题。 maven的默认编译使用的jdk版本貌似很低,使用maven-compiler-plugin插件可以指定项目源码的jdk版本,编译后的jdk版本,以及编码。 <plugin>

  • 简介 compiler插件3.0之前,默认的Java编译器就的JDK自带的javac。但是从Compiler插件3.0开始(需要JDK1.6),默认的Java编译器 是javax.tools.JavaCompiler。如果仍然希望使用JDK自带的javac编译源代码,就需要为mvn命令配置forceJavacCompilerUse启动参数如:-Dmaven.compiler.forceJavacC

  • 先定义一个父组件todo-list,和子组件 <!-- 父组件--> <template> <div> <ul> <slot>当父组件不填充内容时候,展示这行文字</slot> </ul> </div> </template> <script> export default { name: 'todo-list' }

  •  用法和iview差不多,但是比iview多了一层。 <template slot-scope="scope"> <span v-for="(item, index) in returnTypeList" :key="index" v-show="item.key === scope.row.returnType">{{item.value}}</span> </templa

 相关资料
  • 执行Spring Boot代码时,我得到如下错误: 执行目标组织失败。springframework。启动:spring boot maven插件:2.1.2。版本:在项目projectName上运行(默认cli):找不到合适的主类,请添加“mainClass”属性 我如何解决这个问题?

  • 我正在尝试使用maven assembly插件生成zip文件程序集。我只剩下两个问题,我想知道是否有可能仅仅通过配置来解决,但作为最后的手段,我也在考虑编写自己的maven插件来扩展maven assembly插件 丢失的两块是 > 将与include模式匹配的每个依赖项放入其自己的 这是我的程序集的相关部分 这将使用

  • 可靠的扩展 目前开源社区有不少人为Sanic框架编写了插件,这些插件很可能会在将来的某个时间帮助到你,比如缓存、模板渲染、api文档生成、Session...等等 官方也维护了一个扩展列表,见extensions

  • 该插件为 changed.jstree 事件添加了更多信息。新数据包含在changed 事件数据属性中,并包含 selected 和 deselected 节点的列表。 changed.jstree Eventchanged plugin 选择更改时触发 (the "changed" plugin enhances the original event with more data) nodeOb

  • moye插件机制 出于性能考虑, moye控件只保留最小功能集合. 许多增强功能是由插件来协助完成的. 例如, 在获取校验码按钮一般情况都有一个冷却时间60秒. 点击之后60秒内是禁用的, 此时按钮文字显示冷却时间的倒计时. 此功能不方便直接写在Button控件中, 即可编写一个插件来完成. 使用方式 可以使用两种方式来激活一个控件 1、通过构造参数plugins require('moye/pl

  • 问题内容: 我目前正在从事Java 11迁移项目,其中jaxb2-maven-plugin已用于XJC任务。由于JDK 11版本中没有XJC可执行文件,因此出现以下错误。 下面是我的pom.xml 根据Java 11的要求,我添加了必要的依赖项,例如JAXB,JAXB-IMPL等。但是仍然无法解决问题。您对此有任何建议的解决方法吗?预先感谢。 问题答案: 我通过以下参考链接解决了此问题。 http