Flink plugin机制,结合SPI和自定义ClassLoader实现,允许冲突jar包并存,不用再修改代码等方式来统一class版本。
下面代码模拟plugin的实现流程
public interface IShout {void shout();boolean valid(String config);}public class Cat implements IShout {@Overridepublic void shout() {System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile());System.out.println("miao miao");}@Overridepublic boolean valid(String config) {return config.equalsIgnoreCase("cat");}}public class Dog implements IShout {@Overridepublic void shout() {System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile());System.out.println("wang wang");}@Overridepublic boolean valid(String config) {return config.equalsIgnoreCase("dog");}}public class MyClassLoader extends URLClassLoader {public MyClassLoader(URL[] urls) {super(urls);}@Overrideprotected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {Class<?> c = findLoadedClass(name);if (c == null) {try {//优先从当前路径下加载classc = findClass(name);} catch (ClassNotFoundException e) {c=getParent().loadClass(name);}}if (resolve) {resolveClass(c);}return c;}}}public class SPIMain {public static void main(String[] args) throws IOException {Path path = Files.createTempDirectory(Paths.get("c:/workspace/tmp"),"spi");// path.toFile().deleteOnExit();String catPath = Cat.class.getCanonicalName().replace(".", "/") + ".class";File file = path.resolve(catPath).toFile();file.getParentFile().mkdirs();Files.copy(SPIMain.class.getClassLoader().getResourceAsStream(catPath), file.toPath());ClassLoader subModuleClassLoader = new MyClassLoader(new URL[]{path.toUri().toURL()});ServiceLoader<IShout> shouts = ServiceLoader.load(IShout.class,subModuleClassLoader);String config="cat";IShout shout = null;for (IShout s : shouts) {s.shout();if(s.valid(config)){shout = s;break;}}shout.shout();IShout cat = new Cat();cat.shout();}}
程序输出:
/C:/workspace/github/JavaTest/java-test/target/classes/wang wang/c:/workspace/tmp/spi4806402692415880585/miao miao/c:/workspace/tmp/spi4806402692415880585/miao miao/C:/workspace/github/JavaTest/java-test/target/classes/miao miao
