您的位置:首页 > 编程语言 > Java开发

PlugFace重生:Java 插件系统

2020-04-30 12:19 1826 查看

一年前,我遇到了将代码部分动态加载到Java应用程序中的需要,而不必每次都重新编译或重新打包我的软件。基本上,我在寻找插件系统。

当时只有一个值得一提的开源插件系统PF4J,但是我觉得它有点笨拙和麻烦。我想要一些简单的东西,我可以在几分钟内提高生产力。所以我决定自己写。

输入PlugFace
第一次迭代简直太糟糕了,因为当时我只是公司的一名实习生,仍然在学习实际的Java,并且不具备编写良好,可用框架的知识。

缺点

第一个实现不是我想要的那么简单。
有实现的接口,要使用的反射,要编写的配置文件,沙盒许可系统,插件之间的依赖项注入半工半断的尝试,以及编写和使用它们的大量汗水它。
这不是世界上最伟大的软件。
这是旧的PlugFace插件的示例:

[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f9690e">package</span> <span style="color:#f8f8f2">org</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">plugface</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">demo</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">plugins</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">greet</span><span style="color:#f9690e">;</span>

<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.Plugin</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.PluginConfiguration</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.PluginStatus</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.demo.app.sdk.Greeter</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.impl.DefaultPluginConfiguration</span><span style="color:#f9690e">;</span>

<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">java.util.Collections</span><span style="color:#f9690e">;</span>

<span style="color:#f39c12">public</span> <span style="color:#f39c12">class</span> <span style="color:#7ed07e">GreeterPlugin</span> <span style="color:#f39c12">implements</span> <span style="color:#7ed07e">Plugin</span><span style="color:#f9690e"><</span><span style="color:#7ed07e">String</span><span style="color:#f9690e">[],</span> <span style="color:#7ed07e">String</span><span style="color:#f9690e">>,</span> <span style="color:#7ed07e">Greeter</span><span style="color:#f9690e">{</span>

<span style="color:#f39c12">private</span> <span style="color:#f39c12">final</span> <span style="color:#7ed07e">String</span> <span style="color:#f8f8f2">name</span><span style="color:#f9690e">;</span>
<span style="color:#f39c12">private</span> <span style="color:#7ed07e">PluginConfiguration</span> <span style="color:#f8f8f2">configuration</span><span style="color:#f9690e">;</span>
<span style="color:#f39c12">private</span> <span style="color:#7ed07e">PluginStatus</span> <span style="color:#f8f8f2">status</span><span style="color:#f9690e">;</span>
<span style="color:#f39c12">private</span> <span style="color:#f39c12">boolean</span> <span style="color:#f8f8f2">enabled</span><span style="color:#f9690e">;</span>

<span style="color:#f39c12">public</span> <span style="color:#7ed07e">GreeterPlugin</span> <span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f8f8f2">name</span> <span style="color:#f9690e">=</span> <span style="color:#f2ca27">"greeter"</span><span style="color:#f9690e">;</span>
<span style="color:#f8f8f2">configuration</span> <span style="color:#f9690e">=</span> <span style="color:#f39c12">new</span> <span style="color:#7ed07e">DefaultPluginConfiguration</span><span style="color:#f9690e">();</span>
<span style="color:#f8f8f2">status</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">PluginStatus</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">READY</span><span style="color:#f9690e">;</span>
<span style="color:#f8f8f2">enabled</span> <span style="color:#f9690e">=</span> <span style="color:#f39c12">false</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">start</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">throw</span> <span style="color:#f39c12">new</span> <span style="color:#7ed07e">UnsupportedOperationException</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"This plugin operates in single mode only"</span><span style="color:#f9690e">);</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">stop</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">throw</span> <span style="color:#f39c12">new</span> <span style="color:#7ed07e">UnsupportedOperationException</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"This plugin operates in single mode only"</span><span style="color:#f9690e">);</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">String</span> <span style="color:#7ed07e">execute</span><span style="color:#f9690e">(</span><span style="color:#7ed07e">String</span><span style="color:#f9690e">[]</span> <span style="color:#f8f8f2">parameters</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#7ed07e">greet</span><span style="color:#f9690e">();</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">PluginConfiguration</span> <span style="color:#7ed07e">getPluginConfiguration</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#f9690e">(</span><span style="color:#7ed07e">PluginConfiguration</span><span style="color:#f9690e">)</span> <span style="color:#7ed07e">Collections</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">unmodifiableMap</span><span style="color:#f9690e">(</span><span style="color:#f8f8f2">configuration</span><span style="color:#f9690e">);</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">setPluginConfiguration</span><span style="color:#f9690e">(</span><span style="color:#7ed07e">PluginConfiguration</span> <span style="color:#f8f8f2">configuration</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">this</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">configuration</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">configuration</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">String</span> <span style="color:#7ed07e">getName</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#f8f8f2">name</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">PluginStatus</span> <span style="color:#7ed07e">getStatus</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#f8f8f2">status</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">setStatus</span><span style="color:#f9690e">(</span><span style="color:#7ed07e">PluginStatus</span> <span style="color:#f8f8f2">pluginStatus</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span>
<span style="color:#f8f8f2">status</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">pluginStatus</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">enable</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">this</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">enabled</span> <span style="color:#f9690e">=</span> <span style="color:#f39c12">true</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">disable</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">this</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">enabled</span> <span style="color:#f9690e">=</span> <span style="color:#f39c12">false</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">boolean</span> <span style="color:#7ed07e">isEnabled</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#f8f8f2">enabled</span> <span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">String</span> <span style="color:#7ed07e">greet</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#f2ca27">"Hello PlugFace!"</span><span style="color:#f9690e">:</span>
<span style="color:#f9690e">}</span>

<span style="color:#f9690e">}</span>
</code></span></span>

这些东西简直是怪物,界面巨大,并且充满了可争议的有用功能(例如状态和名称),并且不实用。
如果您想要比“开始”、“停止”和“执行”更复杂的行为,则必须添加自己的接口并将插件转换为该类型,才能使用它或通过反射访问方法。

这时我突然有了一个主意。当框架只能处理动态类加载时,为什么要限制用户与插件的交互方式呢?

优点

随着0.6版的发布,这个框架又复活了。这是(几乎)完整的重写。我抛弃了整个接口故事,取而代之的是一个更简洁的@Plugin(“name”)注释,对你的插件应该如何表现没有任何意见。只需让它实现应用程序知道的一些接口,然后通过它访问它。

这是相同的插件,但带有新系统:

[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f9690e">package</span> <span style="color:#f8f8f2">org</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">plugface</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">demo</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">plugins</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">greet</span><span style="color:#f9690e">;</span>

<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.core.annotations.Plugin</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.demo.app.sdk.Greeter</span><span style="color:#f9690e">;</span>

<span style="color:#7ed07e">@Plugin</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"greeter"</span><span style="color:#f9690e">)</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">class</span> <span style="color:#7ed07e">GreeterPlugin</span> <span style="color:#f39c12">implements</span> <span style="color:#7ed07e">Greeter</span> <span style="color:#f9690e">{</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">String</span> <span style="color:#7ed07e">greet</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#f2ca27">"Hello PlugFace!"</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>
<span style="color:#f9690e">}</span>
</code></span></span>

它实现了

Greeter
我的应用程序提供的接口。现在,我的代码可以简单地检索插件并将其放入Greeter类型的变量中,而无需了解
GreeterPlugin
类。整齐!

这是我的应用程序代码。

[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f39c12">final</span> <span style="color:#7ed07e">PluginManager</span> <span style="color:#f8f8f2">manager</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">PluginManagers</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">defaultPluginManager</span><span style="color:#f9690e">();</span>

<span style="color:#f8f8f2">manager</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">loadPlugins</span><span style="color:#f9690e">(</span><span style="color:#7ed07e">PluginSources</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">jarSource</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"path/to/my/plugin/jars"</span><span style="color:#f9690e">));</span>

<span style="color:#f39c12">final</span> <span style="color:#7ed07e">Greeter</span> <span style="color:#f8f8f2">greeter</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">manager</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">getPlugin</span><span style="color:#f9690e">(</span><span style="color:#7ed07e">Greeter</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">class</span><span style="color:#f9690e">);</span>

<span style="color:#f8f8f2">greeter</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">greet</span><span style="color:#f9690e">();</span> <span style="color:#808080">// => "Hello PlugFace!"</span>
</code></span></span>

PluginManager是一个从各种来源加载插件的实用工具类,这是对旧版本的另一个改进,旧版本只以硬编码JAR加载为特色,并且通过名字和类型访问PluginContext来添加/获取/删除插件。

我还完全放弃了沙盒功能,该功能利用Java SecurityContext功能将插件限制在允许的范围内。由于处理起来很麻烦,我宁愿将其完全删除以专注于此新版本的核心功能。如果我找到一种方便的方式来实现它,我可能会在将来的版本中重新引入它。

依赖注入正确完成

旧系统试图引入的一个特性是插件相互注入的可能性。它通过将插件放入PluginConfiguration对象(基本上是一个美化过的Map<String,对象>,它可以工作,但是使用起来相当不实际。

PlugFace 0.6通过构造器使用标准

@javax.inject.Inject
注释(功能齐全,将来会在出现单个构造器的情况下成为可选的)引入了完整的依赖项注入系统,因此插件类可与任何标准DI框架(例如Spring)一起使用Guice
它支持使用拓扑排序的复杂依赖关系图,以及循环依赖关系检测和所有这些好东西。

[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f9690e">package</span> <span style="color:#f8f8f2">org</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">plugface</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">demo</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">plugins</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">math</span><span style="color:#f9690e">;</span>

<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.core.annotations.Plugin</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.demo.app.sdk.Mathematics</span><span style="color:#f9690e">;</span>

<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">javax.inject.Inject</span><span style="color:#f9690e">;</span>

<span style="color:#7ed07e">@Plugin</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"math"</span><span style="color:#f9690e">)</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">class</span> <span style="color:#7ed07e">MathPlugin</span> <span style="color:#f39c12">implements</span> <span style="color:#7ed07e">Mathematics</span> <span style="color:#f9690e">{</span>

<span style="color:#f39c12">private</span> <span style="color:#f39c12">final</span> <span style="color:#7ed07e">SumPlugin</span> <span style="color:#f8f8f2">sum</span><span style="color:#f9690e">;</span>
<span style="color:#f39c12">private</span> <span style="color:#f39c12">final</span> <span style="color:#7ed07e">MultPlugin</span> <span style="color:#f8f8f2">mult</span><span style="color:#f9690e">;</span>

<span style="color:#7ed07e">@Inject</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">MathPlugin</span><span style="color:#f9690e">(</span><span style="color:#7ed07e">SumPlugin</span> <span style="color:#f8f8f2">sum</span><span style="color:#f9690e">,</span> <span style="color:#7ed07e">MultPlugin</span> <span style="color:#f8f8f2">mult</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">this</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">sum</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">sum</span><span style="color:#f9690e">;</span>
<span style="color:#f39c12">this</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">mult</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">mult</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">Integer</span> <span style="color:#7ed07e">sum</span><span style="color:#f9690e">(</span><span style="color:#f39c12">int</span> <span style="color:#f8f8f2">a</span><span style="color:#f9690e">,</span> <span style="color:#f39c12">int</span> <span style="color:#f8f8f2">b</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#f8f8f2">sum</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">sum</span><span style="color:#f9690e">(</span><span style="color:#f8f8f2">a</span><span style="color:#f9690e">,</span> <span style="color:#f8f8f2">b</span><span style="color:#f9690e">);</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">Integer</span> <span style="color:#7ed07e">mult</span><span style="color:#f9690e">(</span><span style="color:#f39c12">int</span> <span style="color:#f8f8f2">a</span><span style="color:#f9690e">,</span> <span style="color:#f39c12">int</span> <span style="color:#f8f8f2">b</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">return</span> <span style="color:#f8f8f2">mult</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">mult</span><span style="color:#f9690e">(</span><span style="color:#f8f8f2">a</span><span style="color:#f9690e">,</span> <span style="color:#f8f8f2">b</span><span style="color:#f9690e">);</span>
<span style="color:#f9690e">}</span>
<span style="color:#f9690e">}</span>
</code></span></span>

Spring Integration

Spring框架是Java中非常有用的工具包。它几乎具有任何功能,但其核心功能显然是依赖注入系统。由于我几乎在所有项目中都使用Spring,因此我希望PlugFace与它能够很好地集成。

如果你想使用普通的PlugFace,你可以导入plugin -core模块,但是如果你使用Spring,你可能需要切换到特殊的plugin - Spring模块。
它不仅为PluginManager和PluginContext使用自动配置的bean,而且还增加了对从中检索插件的支持

ApplicationContext
(这意味着如果未将对象作为插件找到,它将在Spring bean中进行查找),也许更重要的是,它使Spring bean成为插件中依赖项注入的可行目标。

没错,有了plugin - Spring,你不仅可以在你的插件中注入其他的插件,还可以在你的应用中注册任何Spring bean。

您的插件可以访问服务类、存储库、实用程序单例,基本上所有内容都可以在Spring上下文中找到。

[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f9690e">package</span> <span style="color:#f8f8f2">org</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">plugface</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">demo</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">plugins</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">user</span><span style="color:#f9690e">;</span>

<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.core.annotations.Plugin</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.demo.app.sdk.Greeter</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">org.plugface.demo.app.sdk.TestService</span><span style="color:#f9690e">;</span>

<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">javax.inject.Inject</span><span style="color:#f9690e">;</span>

<span style="color:#7ed07e">@Plugin</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"greeter"</span><span style="color:#f9690e">)</span>
<span style="color:#f39c12">public</span> <span style="color:#f39c12">class</span> <span style="color:#7ed07e">UserPlugin</span> <span style="color:#f39c12">implements</span> <span style="color:#7ed07e">UserDetails</span> <span style="color:#f9690e">{</span>

<span style="color:#f39c12">private</span> <span style="color:#f39c12">final</span> <span style="color:#7ed07e">UserService</span> <span style="color:#f8f8f2">userService</span><span style="color:#f9690e">;</span> <span style="color:#808080">//this is a Spring service</span>

<span style="color:#7ed07e">@Inject</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">GreeterPlugin</span><span style="color:#f9690e">(</span><span style="color:#7ed07e">UserService</span> <span style="color:#f8f8f2">userService</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">this</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">userService</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">userService</span><span style="color:#f9690e">;</span>
<span style="color:#f9690e">}</span>

<span style="color:#7ed07e">@Override</span>
<span style="color:#f39c12">public</span> <span style="color:#7ed07e">String</span> <span style="color:#7ed07e">getUsername</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span>
<span style="color:#f39c12">final</span> <span style="color:#7ed07e">User</span> <span style="color:#f8f8f2">user</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">userService</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">getUserById</span><span style="color:#f9690e">(</span><span style="color:#dda0dd">0L</span><span style="color:#f9690e">);</span>
<span style="color:#f39c12">return</span> <span style="color:#f8f8f2">user</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">getUsername</span><span style="color:#f9690e">();</span>
<span style="color:#f9690e">}</span>
<span style="color:#f9690e">}</span>
</code></span></span>

从现在开始

将来,我还想与Guice等其他DI框架集成,并在出现新的Java插件用例时扩展当前的功能集。
在此之前,感谢您的关注,并祝您编程愉快!

原文链接:https://dev.to//matteojoliveau/plugface-reborn---the-java-plugin-system-18bm

cunxiedian8614 原创文章 0获赞 2访问量 2万+ 关注 私信
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: