目录

编辑

1、初识PF4J

 2、pf4j 与 SpringBoot 集成

     2-1、封装starter

        ①、引入pom依赖

        ②、创建属性类

        ③、创建自动配置类

        ④ 创建 spring.factories 资源文件【resources/META-INFO/】

    2-2、starter使用        

        ①、引入封装的starter

        ②、定义扩展标记点

        ③、开发扩展类


1、初识PF4J

        使扩展插件以jar、zip 形式进行动态加载到应用程序

        参考官网:PF4J : PF4J

        

springboot集成pf4j springboot pf4j_maven

中文:

springboot集成pf4j springboot pf4j_java_02

官网提供4个扩展:

      pf4j-update : pf4j 更新机制

      pf4j-spring  :    pf4j 与 Spring 框架集成 (将插件扩展类注册为SpringBean)

      pf4j-web  :    Web 应用 引入 pf4j

      pf4j-wicket :  wicket插件框架

  以上引入方式可参考官网扩展工程代码 与SpringBoot 集成可参考2章节

 2、pf4j 与 SpringBoot 集成

     2-1、封装starter

        可以使用IDE工具直接创建一个SpringBoot工程或者maven工程        

        ①、引入pom依赖

        spring-boot-autoconfigure :提供自动装配功能的核心依赖 ;【必须】

        spring-boot-configuration-processor:自定义的配置类生成元数据方便IDEA代码提示 【非必须】

        参考pom.xml :

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ap</groupId>
    <artifactId>pf4j3-spring-boot-starter</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>pf4j3-spring-boot-starter</name>
    <description>pf4j3-spring-boot-starter</description>
    <properties>
        <java.version>8</java.version>
        <pf4j.version>3.8.0</pf4j.version>
        <pf4j-spring.version>0.8.0</pf4j-spring.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 自动装配核心依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <!-- 配置元信息 idea代码提示用-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- pf4j包 -->
        <dependency>
            <groupId>org.pf4j</groupId>
            <artifactId>pf4j</artifactId>
            <version>${pf4j.version}</version>
        </dependency>
        <!-- pfj4 与 spring 集成 -->
        <dependency>
            <groupId>org.pf4j</groupId>
            <artifactId>pf4j-spring</artifactId>
            <version>${pf4j-spring.version}</version>
            <!-- 排除日志包 -->
            <exclusions>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>


</project>

        ②、创建属性类

        仅提供基本的配置属性项:【可根据pf4j源码进行更多扩展】

                enabled : 启用开关 ; runtimeMode: 运行模式; path:扩展目录(pf4j扫包位置)

                运行模式的详情介绍可以参考官网:PF4J : Development mode

                开发模式好处:更多的日志内容输出 、无需打包【扫描插件工程编译的target/classes】

             

package com.ap.pf4j3.spring.boot.property;

import org.pf4j.RuntimeMode;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author AP
 * @date 2023/3/26
 * @apiNote
 */
@ConfigurationProperties(prefix = Pf4j3Properties.PREFIX )
public class Pf4j3Properties {

    public static final String PREFIX = "spring.pf4j";

    /**
     * 是否启用
     */
    private boolean enabled = false;

    /**
     * 运行模式:development、 deployment
     */
    private RuntimeMode runtimeMode = RuntimeMode.DEPLOYMENT;

    /**
     * 扩展插件目录:可配置绝对路径和相对路径 可选项 【默认项目root\plugins】
     */
    private String path = "plugins";


    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public RuntimeMode getRuntimeMode() {
        return this.runtimeMode;
    }
    public void setRuntimeMode(RuntimeMode runtimeMode) {
        this.runtimeMode = runtimeMode;
    }
}

        ③、创建自动配置类

package com.ap.pf4j3.spring.boot.config;

import com.ap.pf4j3.spring.boot.property.Pf4j3Properties;
import org.pf4j.AbstractPluginManager;
import org.pf4j.PluginManager;
import org.pf4j.RuntimeMode;
import org.pf4j.spring.SpringPluginManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.io.File;
import java.nio.file.Paths;

/**
 * @author AP
 * @date 2023/3/26
 * @apiNote
 */
@Configuration
@EnableConfigurationProperties(Pf4j3Properties.class)
@ConditionalOnProperty(prefix = Pf4j3Properties.PREFIX, value = "enabled", havingValue = "true")
public class Pf4j3AutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public PluginManager pluginManager(Pf4j3Properties pf4j3Properties) {
        // 设置运行模式
        System.setProperty(AbstractPluginManager.MODE_PROPERTY_NAME, pf4j3Properties.getRuntimeMode().toString());

        return new SpringPluginManager(Paths.get(pf4j3Properties.getPath()));
    }

}

        ④ 创建 spring.factories 资源文件【resources/META-INFO/】

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ap.pf4j3.spring.boot.config.Pf4j3AutoConfiguration

    2-2、starter使用        

        ①、引入封装的starter

<!--pf4j插件服务-->
    <dependency>
        <groupId>com.ap</groupId>
        <artifactId>plugins-spring-boot-starter</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </dependency>

        ②、配置application.yml 

       【开发模式时:需要提供资源文件 MANIFEST.MF】

spring:
  pf4j:
    #启用开关
    enabled: true
    #运行模式:development(开发模式)、 deployment(部署模式)
    runtime-mode: deployment
    #扩展插件目录:可配置绝对路径和相对路径 可选项 【默认项目root\plugins】
    path: plugins

       或 application.properties

spring.pf4j.enabled=true
spring.pf4j.path=plugins
spring.pf4j.runtime-mode=deployment

        ②、定义扩展标记点

                参考官网 【标记点可以是一个抽象类或接口】

springboot集成pf4j springboot pf4j_maven_03

        ③、开发扩展类

                pom定义

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <properties>
        <plugin.id>${project.artifactId}</plugin.id><!-- 必需项 -->
        <plugin.class/> <!-- 自定义实现plugin时需要定义 -->
        <plugin.version>${project.version}</plugin.version> <!-- 必需项 -->
        <plugin.provider>${user.name}</plugin.provider>
        <plugin.dependencies/> <!-- 依赖其他插件时定义 -->
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.2</version>
                <configuration>
                    <outputDirectory>
                        ${user.dir}/plugins <!--插件jar包输出目录位置-->
                    </outputDirectory>
                    <archive>
                        <!-- MANIFEST.MF 文件 -->
                        <manifestEntries>
                            <Plugin-Id>${plugin.id}</Plugin-Id>
                            <Plugin-Version>${plugin.version}</Plugin-Version>
                            <Plugin-Provider>${plugin.provider}</Plugin-Provider>
                            <Plugin-Class>${plugin.class}</Plugin-Class>
                            <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

        开发插件:

                1、继承 springPlugin

                2、扩展类增加注解@Extension         

        参考官网 

                【官网例子是 静态内部类形式, 此处可拆分为两个独立的类,若工程不需要管理插件则无需继承 plugin / springPlugin】

springboot集成pf4j springboot pf4j_maven_04