首页 > 其他分享 >spring-plugin简单使用

spring-plugin简单使用

时间:2024-02-05 09:33:06浏览次数:48  
标签:plugin spring boot jar 简单 org com

spring-plugin 是spring 官方提供的一个插件化设计方案,比如使用支持基于spring 的项目

项目结构

此简单测试项目是一个maven 多模块的,包含了一个plugin 契约模块,连个插件实现,以及一个bootstrap 启动入口

  • 代码结构
├── README.md
├── bootstrap
│   ├── HELP.md
│   ├── pom.xml
│   └── src
│       └── main
│           ├── java
│           │   └── com
│           │       └── dalongplugin
│           │           └── bootstrap
│           │               ├── BootstrapApplication.java
│           │               └── demos
│           │                   └── web
│           │                       └── Api.java
│           └── resources
│               ├── application.properties
│               └── static
│                   └── index.html
├── plugin_a
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── com
│       │   │       └── dalongplugina
│       │   │           └── PluginA.java
│       │   └── resources
│       └── test
│           └── java
├── plugin_b
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── com
│       │   │       └── dalongpluginb
│       │   │           └── PluginB.java
│       │   └── resources
│       └── test
│           └── java
├── plugin_interface
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── com
│       │   │       └── dalongpluginb
│       │   │           └── PluginContract.java
│       │   └── resources
│       └── test
│           └── java
└── pom.xml

代码说明

  • plugin_interface
    就是一个接口定义
 
package com.dalongpluginb;
 
import org.springframework.plugin.core.Plugin;
 
public interface PluginContract extends Plugin<String> {
    String message(String input);
}

引用的包

<dependencies>
        <dependency>
            <groupId>org.springframework.plugin</groupId>
            <artifactId>spring-plugin-core</artifactId>
        </dependency>
</dependencies>
  • plugina 实现
package com.dalongplugina;
 
import com.dalongpluginb.PluginContract;
import org.springframework.stereotype.Component;
 
@Component
public class PluginA implements PluginContract {
    @Override
    public String message(String input) {
        return String.format("plugina: %s", input);
    }
    @Override
    public boolean supports(String s) {
        return s.equalsIgnoreCase("plugina");
    }
}

maven 依赖

<dependencies>
        <dependency>
            <groupId>com.dalong</groupId>
            <artifactId>plugin_interface</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>
</dependencies>

pluginb 类似

  • bootstrap 入口
    一个spring boot 项目,同时会添加插入契约定义,默认是一个spring boot web 项目
    maven 依赖
 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dalong</groupId>
    <artifactId>bootstrap</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>bootstrap</name>
    <description>bootstrap</description>
    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.4.2</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
       // spring-plugin 依赖添加
        <dependency>
            <groupId>org.springframework.plugin</groupId>
            <artifactId>spring-plugin-core</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.plugin</groupId>
            <artifactId>spring-plugin-metadata</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.dalong</groupId>
            <artifactId>plugin_a</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.dalong</groupId>
            <artifactId>plugin_b</artifactId>
            <version>1.0-SNAPSHOT</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.dalong</groupId>
            <artifactId>plugin_interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
 
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <archive>
                        // 移除jar maven 构建信息 
                        <addMavenDescriptor>false</addMavenDescriptor>
                    </archive>
                </configuration>
            </plugin>
          // 为了方便插件的加载没有使用spring boot 的fat jar 插件
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>
                                ${project.build.directory}/libs
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
 
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <mainClass>com.dalongplugin.bootstrap.BootstrapApplication</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
</project>
  • 入口代码
package com.dalongplugin.bootstrap;
 
import com.dalongpluginb.PluginContract;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.plugin.core.config.EnablePluginRegistries;
 
// 通过scanBasePackages 配置需要进行的包扫描,间接解决插件加载的问题
@SpringBootApplication(scanBasePackages = {"com.dalongpluginb","com.dalongplugin.bootstrap","com.dalongplugina"})
// 进行插件扫描
@EnablePluginRegistries(PluginContract.class)
public class BootstrapApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(BootstrapApplication.class, args);
    }
    // ApplicationRunner 启动之后进行插件的调用,主要是测试
    @Bean
    public ApplicationRunner runner(PluginRegistry<PluginContract,String> plugins) {
        return args -> {
            plugins.forEach(plugin -> {
                System.out.println(plugin.message("hello"));
            });
        };
    }
}

使用效果

因为默认本地开发插件都加载了(maven 配置了),因为我们使用的是通过外部classpath 模式,所以可以随时进行插件的添加以及移除

  • 构建
mvn clean package
  • bootstrap 效果
├── bootstrap-0.0.1-SNAPSHOT.jar
└── libs
    ├── accessors-smart-1.2.jar
    ├── android-json-0.0.20131108.vaadin1.jar
    ├── apiguardian-api-1.1.0.jar
    ├── asm-5.0.4.jar
    ├── assertj-core-3.18.1.jar
    ├── byte-buddy-1.10.19.jar
    ├── byte-buddy-agent-1.10.19.jar
    ├── hamcrest-2.2.jar
    ├── jackson-annotations-2.11.4.jar
    ├── jackson-core-2.11.4.jar
    ├── jackson-databind-2.11.4.jar
    ├── jackson-datatype-jdk8-2.11.4.jar
    ├── jackson-datatype-jsr310-2.11.4.jar
    ├── jackson-module-parameter-names-2.11.4.jar
    ├── jakarta.activation-api-1.2.2.jar
    ├── jakarta.annotation-api-1.3.5.jar
    ├── jakarta.el-3.0.3.jar
    ├── jakarta.xml.bind-api-2.3.3.jar
    ├── json-path-2.4.0.jar
    ├── json-smart-2.3.jar
    ├── jsonassert-1.5.0.jar
    ├── jul-to-slf4j-1.7.30.jar
    ├── junit-jupiter-5.7.0.jar
    ├── junit-jupiter-api-5.7.0.jar
    ├── junit-jupiter-engine-5.7.0.jar
    ├── junit-jupiter-params-5.7.0.jar
    ├── junit-platform-commons-1.7.0.jar
    ├── junit-platform-engine-1.7.0.jar
    ├── log4j-api-2.13.3.jar
    ├── log4j-to-slf4j-2.13.3.jar
    ├── logback-classic-1.2.3.jar
    ├── logback-core-1.2.3.jar
    ├── mockito-core-3.6.28.jar
    ├── mockito-junit-jupiter-3.6.28.jar
    ├── objenesis-3.1.jar
    ├── opentest4j-1.2.0.jar
    ├── plugin_a-1.0-SNAPSHOT.jar
    ├── plugin_b-1.0-SNAPSHOT.jar
    ├── plugin_interface-1.0-SNAPSHOT.jar
    ├── slf4j-api-1.7.30.jar
    ├── snakeyaml-1.27.jar
    ├── spring-aop-5.3.3.jar
    ├── spring-beans-5.3.3.jar
    ├── spring-boot-2.4.2.jar
    ├── spring-boot-autoconfigure-2.4.2.jar
    ├── spring-boot-starter-2.4.2.jar
    ├── spring-boot-starter-json-2.4.2.jar
    ├── spring-boot-starter-logging-2.4.2.jar
    ├── spring-boot-starter-test-2.4.2.jar
    ├── spring-boot-starter-tomcat-2.4.2.jar
    ├── spring-boot-starter-web-2.4.2.jar
    ├── spring-boot-test-2.4.2.jar
    ├── spring-boot-test-autoconfigure-2.4.2.jar
    ├── spring-context-5.3.3.jar
    ├── spring-core-5.3.3.jar
    ├── spring-expression-5.3.3.jar
    ├── spring-jcl-5.3.3.jar
    ├── spring-plugin-core-2.0.0.RELEASE.jar
    ├── spring-plugin-metadata-2.0.0.RELEASE.jar
    ├── spring-test-5.3.3.jar
    ├── spring-web-5.3.3.jar
    ├── spring-webmvc-5.3.3.jar
    ├── tomcat-embed-core-9.0.41.jar
    ├── tomcat-embed-websocket-9.0.41.jar
    └── xmlunit-core-2.7.0.jar

默认运行效果

移除一个插件的效果

说明

实际上目前也是有不少缺陷的,比如类java,外部jar 加载,以及类隔离的一些问题,同时也缺少维护了,但是对于简单项目还是很不错的,可以使用

参考资料

https://github.com/spring-projects/spring-plugin
https://github.com/rongfengliang/spring-plugin-learning

标签:plugin,spring,boot,jar,简单,org,com
From: https://www.cnblogs.com/rongfengliang/p/18007403

相关文章

  • 苏维埃日报06.栈与队列的最简单实现(?)
    前言当年学数据结构的时候被栈和队列虐傻了当年真的没搞清这俩的进出顺序现在回过头来发现,退役了反而有点会了一个不恰当的比喻就像核糖体在mRNA上合成肽链一样,栈和队列的数据读入也是逐个读入但输出的时候,数据是带特定顺序输出的,如栈先进后出,队列先进先出,但是线性多肽水解......
  • SpringBoot实现统一异常处理
    目录前言实现步骤定义统一响应对象类定义业务异常枚举接口和实现定义业务异常基类定义全局异常处理切面测试和验证总结前言近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功......
  • 全网最全:SpringBoot 各种回滚骚操作实战
    事务定义事务,就是一组操作数据库的动作集合。事务是现代数据库理论中的核心概念之一。如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事务。当所有的步骤像一个操作一样被完整地执行,我们称该事务被提交。由于其中的一部分或多步执行失败,导致没有步骤被提交......
  • 四、SpringCloud alibaba 之 OpenFeign
    4.1、调用过程的演化JAVA项目中如何实现接口调用?远程调用工具描述HttpClientHttpClient是ApacheJakartaCommon下的子项目,用来提供高效的、最新的、功能丰富的支持Http协议的客户端编程工具包,并且它支持HTTP协议最新版本和建议。HttpClient相比传统JDK自......
  • spring cloud与加密库jasypt(ulisesbocchio)冲突问题定位
    背景最近在项目上遇到个问题。项目就是普通的springcloud,springcloud在springboot的基础上多了一些东西,比如支持bootstrap上下文(通过bootstrap.yml/properties配置)。另外呢,我们这边要求上线的时候,要把配置文件里的敏感配置如密码,进行加密。加密的话,我们这边用了如下库:<depend......
  • 开发小技巧 - springboot项目启动控制台输出访问地址
    在SpringBoot项目中,有时我们需要记录或输出访问的地址和IP,以便进行调试、监控或日志记录。以下是如何在SpringBoot中实现这一需求的方法: 1、编写获取所有访问地址工具类packagecom.example.utils;importcn.hutool.core.util.StrUtil;importorg.springframework.b......
  • SpringBoot连接MySQL
    一、文件结构: 二、实体类packagecom.example.demo.domain;importjava.io.Serializable;importjavax.persistence.Column;importjavax.persistence.Entity;importjavax.persistence.GeneratedValue;importjavax.persistence.Id;importjavax.persistence.Table;......
  • 三种简单负载均衡
    轮询法轮询法是一种简单的负载均衡算法,它将请求依次分配给不同的主机。例如,如果有三个主机A、B、C,那么第一个请求将被分配给主机A,第二个请求将被分配给主机B,第三个请求将被分配给主机C,第四个请求将被分配给主机A,以此类推。具体讲解代码如下publicclassRoundRobinLoadBal......
  • SpringBoot 整合 RabbitMQ
    Docker搭建RabbitMQ拉取RabbitMQ的镜像执行命令dockerpullrabbitmq:3.7-management执行运行命令dockerrun-d--hostnamerabbit--namerabbit-eRABBITMQ_DEFAULT_USER=admin-eRABBITMQ_DEFAULT_PASS=admin-p15672:15672rabbitmq:3-management打开浏览器访问......
  • C++之INI配置文件读写/注释库 inicpp 介绍【简单易用-包含inicpp.hpp头文件即可】
    一个头文件(header-file-only)搞定INI文件读写、甚至进行注释。跨平台,并且用法极其简单。MITlicense,从此配置INI文件就像喝水。【注:对您有帮助的话,Star或Issues为项目维护提供动力,感谢。】-byofficalofJN-inicppproject.一、库下载https://github.com/dujingning/inicpp......