Flink plugin机制,结合SPI和自定义ClassLoader实现,允许冲突jar包并存,不用再修改代码等方式来统一class版本。
下面代码模拟plugin的实现流程
public interface IShout {
void shout();
boolean valid(String config);
}
public class Cat implements IShout {
@Override
public void shout() {
System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile());
System.out.println("miao miao");
}
@Override
public boolean valid(String config) {
return config.equalsIgnoreCase("cat");
}
}
public class Dog implements IShout {
@Override
public void shout() {
System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile());
System.out.println("wang wang");
}
@Override
public boolean valid(String config) {
return config.equalsIgnoreCase("dog");
}
}
public class MyClassLoader extends URLClassLoader {
public MyClassLoader(URL[] urls) {
super(urls);
}
@Override
protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
//优先从当前路径下加载class
c = 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