<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Heck's  Blog]]></title> 
<link>https://www.heckjj.com/index.php</link> 
<description><![CDATA[一瞬间的决定，往往可以改变很多，事实上，让自己成功的往往不是知识，是精神！ 如果你总是为自己找借口，那只好让成功推迟。执行力，今天！]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Heck's  Blog]]></copyright>
<item>
<link>https://www.heckjj.com/post//</link>
<title><![CDATA[PF4J的了解和使用]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[编程杂谈]]></category>
<pubDate>Thu, 24 Nov 2022 14:09:01 +0000</pubDate> 
<guid>https://www.heckjj.com/post//</guid> 
<description>
<![CDATA[ 
	在平时编码过程中我们都知道要抽象，要封装变化，要实现开闭原则，比如对于很多相似的功能，我们可以将通用的功能抽象出来，然后把变化的不同的地方提取出去，比如模版模式、策略模式等都是实现类似的效果<br/><br/>比如对于策略模式，我们通常是定义一个接口，然后有不同的实现，这种是可以的，但是如果通用流程中要扩展的点较多的话，这些不同的实现也需要管理，可以把他们合并到一个单独的包中，再进一步，我们甚至可以将包单独提取出来，支持运行时加载包实现新增功能的支持<br/><br/>JDK对此功能的支持就是 SPI，但是它的限制较多，也不够灵活，比如dubbo就是自己定义了一套SPI的实现，这次我们来看另一个实现，pf4j 提供一套在基本框架中定义扩展点接口，然后通过不同的插件来实现扩展点的功能，来支持对新增开放对修改关闭<br/><br/>下面我们就来学习一下它的使用<br/><br/>使用<br/>比如我们有一套通用的流程，假设是下单流程，不同的业务线等对于下单都有一些特殊点，但是它们的基本流程是相似的，这时候我们就可以先定义好通用的流程，不同的地方预留出扩展点接口，使用 pf4j 的流程如下<br/><br/>先定义好扩展点接口（需要定义单独的包，因为基本应用和各个扩展点的包都依赖它）<br/>定义单独的插件包，其中实现扩展点接口的功能<br/>在应用中编写基本流程和扩展点的发现使用功能<br/>这次我们就参考 pf4j 提供的例子来看一下<br/><br/>1. 定义扩展点接口<br/>pom.xml首先声明依赖<br/><br/>&lt;dependency&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.pf4j&lt;/groupId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;pf4j&lt;/artifactId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;version&gt;3.6.0&lt;/version&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- 一般应用中会依赖这个包，所以这里设置为provided即可 --&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;scope&gt;provided&lt;/scope&gt;<br/>&lt;/dependency&gt;<br/>之后即可声明各个扩展点接口<br/><br/>/**<br/> * 假设我们需要一个通知用户的功能<br/> * 需要注意的是，我们一定要继承 ExtensionPoint 接口，表示这是一个扩展点<br/> */<br/>public interface Notice extends ExtensionPoint &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;boolean notice(List&lt;Long&gt; userIds);<br/>&#125;<br/>2. 各个插件实现<br/>pom.xml修改<br/><br/>&lt;properties&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;maven.compiler.source&gt;8&lt;/maven.compiler.source&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;maven.compiler.target&gt;8&lt;/maven.compiler.target&gt;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- 提供id和版本方便后续排查等使用 --&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;plugin.id&gt;email-plugin&lt;/plugin.id&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;plugin.version&gt;0.0.1&lt;/plugin.version&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- 插件类，如果不关心生命周期可以不提供 --&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;plugin.class /&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;plugin.provider&gt;user1&lt;/plugin.provider&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;plugin.dependencies/&gt;<br/>&lt;/properties&gt;<br/><br/>&lt;dependencies&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- 相关依赖，注意 scope=provided --&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;dependency&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.pf4j&lt;/groupId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;pf4j&lt;/artifactId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;version&gt;3.6.0&lt;/version&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;scope&gt;provided&lt;/scope&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/dependency&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;dependency&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;groupId&gt;com.zavier.demo&lt;/groupId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;extension-api&lt;/artifactId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;scope&gt;provided&lt;/scope&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/dependency&gt;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- 可以定义单独的依赖 --&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;dependency&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;groupId&gt;com.google.guava&lt;/groupId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;guava&lt;/artifactId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;version&gt;30.1.1-jre&lt;/version&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/dependency&gt;<br/>&lt;/dependencies&gt;<br/><br/>&lt;build&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;plugins&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;plugin&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- 配置打包插件，一个是要将所有依赖包打包成一起，避免和其他包冲突，第二是要将插件信息写入到manifest.mf --&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;version&gt;3.1.0&lt;/version&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;configuration&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;descriptorRefs&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;descriptorRef&gt;jar-with-dependencies&lt;/descriptorRef&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/descriptorRefs&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;attach&gt;false&lt;/attach&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;archive&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;manifest&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;addDefaultImplementationEntries&gt;true&lt;/addDefaultImplementationEntries&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/manifest&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;manifestEntries&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Plugin-Id&gt;$&#123;plugin.id&#125;&lt;/Plugin-Id&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Plugin-Version&gt;$&#123;plugin.version&#125;&lt;/Plugin-Version&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Plugin-Provider&gt;$&#123;plugin.provider&#125;&lt;/Plugin-Provider&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Plugin-Class&gt;$&#123;plugin.class&#125;&lt;/Plugin-Class&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Plugin-Dependencies&gt;$&#123;plugin.dependencies&#125;&lt;/Plugin-Dependencies&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/manifestEntries&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/archive&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/configuration&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;executions&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;execution&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;id&gt;make-assembly&lt;/id&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;phase&gt;package&lt;/phase&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;goals&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;goal&gt;single&lt;/goal&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/goals&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/execution&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/executions&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/plugin&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/plugins&gt;<br/>&lt;/build&gt;<br/>功能实现<br/><br/>/**<br/> * 需要实现接口及增加Extension注解<br/> */<br/>@Extension<br/>public class EmailNotice implements Notice &#123;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;@Override<br/>&nbsp;&nbsp;&nbsp;&nbsp;public boolean notice(List&lt;Long&gt; userIds) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// todo逻辑实现<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;final ArrayList&lt;Object&gt; objects = Lists.newArrayList();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;email notice&quot;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&#125;<br/>如果还有其他插件，也是类似的实现<br/><br/>3.插件使用<br/>将之前打包的插件包放到一个路径包下，之后新建一个应用模版，就可以获取插件中的扩展点并使用<br/><br/>public static void main(String[] args) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// 创建的时候，可以指定插件所在的包（其中可以有多个插件包）<br/>&nbsp;&nbsp;&nbsp;&nbsp;PluginManager pluginManager = new DefaultPluginManager(Paths.get(&quot;/u/plugins&quot;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;pluginManager.loadPlugins();<br/>&nbsp;&nbsp;&nbsp;&nbsp;pluginManager.startPlugins();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Long&gt; list = new ArrayList&lt;&gt;();<br/>&nbsp;&nbsp;&nbsp;&nbsp;final List&lt;Notice&gt; extensions = pluginManager.getExtensions(Notice.class);<br/>&nbsp;&nbsp;&nbsp;&nbsp;extensions.forEach(e -&gt; e.notice(list));<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// 也可以获取制定插件中的实现<br/>&nbsp;&nbsp;&nbsp;&nbsp;extensions = pluginManager.getExtensions(Notice.class, &quot;email-plugin&quot;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;extensions.forEach(e -&gt; e.notice(list));<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;pluginManager.stopPlugins();<br/>&nbsp;&nbsp;&nbsp;&nbsp;pluginManager.unloadPlugins();<br/>&#125;<br/>例子代码地址：https://github.com/zavier/pf4j-demo
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post//#blogcomment</link>
<title><![CDATA[[评论] PF4J的了解和使用]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>https://www.heckjj.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>