java插件化开发实例
1.项目分为3个模块 contract,service和plugin,分别提供 契约,服务和插件
2.在新增、编辑、删除插件时,不影响service/contract 本身
3.服务实现对字符串的分割,插件实现通过 逗号(comma)和 Tab键进行splite
4.contract代码如下:
package org.g2.contract; public interface Resolver { /** * 是否支持当前的解析方式 * * @param resolverName 解析方式 * @return */ String getName(); /** * 解析字符串 * * @param args 原始字符 * @return 解析后的字符串 */ String[] resolve(String args); }
5.service的代码如下:
package org.g2.service; import org.g2.contract.Resolver; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; public class ResolverFactory { public static Map<String, Resolver> load() { ServiceLoader<Resolver> resolvers = ServiceLoader.load(Resolver.class); Map<String, Resolver> result = new HashMap<>(); for (Resolver resolver : resolvers) { result.put(resolver.getName(), resolver); } return result; } }
package org.g2.service; import org.g2.contract.Resolver; import java.util.Arrays; import java.util.Map; import java.util.Optional; /** * 入口 */ public class App { public static void main(String[] args) { String content = "Hello,World"; final String type = "comma"; Map<String, Resolver> resolverMap = ResolverFactory.load(); String[] resolve = Optional.ofNullable(resolverMap.get(type)) .orElseThrow(() -> new RuntimeException("不支持的解析类型" + type)) .resolve(content); System.out.println(Arrays.toString(resolve)); content = "Hello\tWorld"; final String type2 = "table"; resolve =Optional.ofNullable(resolverMap.get(type2)) .orElseThrow(() -> new RuntimeException("不支持的解析类型" + type2)) .resolve(content); System.out.println(Arrays.toString(resolve)); } }
6.插件模块(plugin)的代码如下:
package org.g2.plugin.resolver.comma; import org.g2.contract.Resolver; public class CommaResolver implements Resolver{ @Override public String getName() { return "comma"; } @Override public String[] resolve(String args) { return args.split(","); } }
package org.g2.plugin.resolver.table; import org.g2.contract.Resolver; public class TableResolver implements Resolver { @Override public String getName() { return "table"; } @Override public String[] resolve(String args) { return args.split("\t"); } }
另外,需要在plugin本项目的resources里添加 META-INF/services添加文件 org.g2.contract.Resolver (contract接口的完全路径名),文件的值为
org.g2.plugin.resolver.comma.CommaResolver
org.g2.plugin.resolver.table.TableResolver
7.最后对 service和plugin打包,生成两个jar包,上传到linux服务器上后执行如下命令
java -cp plugin-1.0-SNAPSHOT.jar:service-1.0-SNAPSHOT.jar org.g2.service.App
输出如下
[Hello, World]
[Hello, World]
8.后记
在windows 10 的powerShell执行总是不成功,在linux上才成功。
另外如果用
java -cp plugin-1.0-SNAPSHOT.jar -jar service-1.0-SNAPSHOT.jar