通过查看 canal 官方代码 了解 java 实例化 jar 里面的class,这样你肯定知道 项目里面 jar 怎样 读取 并且实例化了,跟着圈圈学技术
总结步骤
- 读取文文件 也就是对应的jar
- 万物皆资源,转换成 url
- 通过 URLClassLoader 加载器加载 反射实例化 就是折磨简单 so easy,你想想 如果你自己 写框架 想要 加载 一些 其他 地方的jar 是不是就 可以 动态加载 并且实例化了
code 如下:
protected void initAlarmHandler() {
logger.info("init alarmHandler begin...");
String alarmHandlerClass = parameters.getAlarmHandlerClass();
String alarmHandlerPluginDir = parameters.getAlarmHandlerPluginDir();
if (alarmHandlerClass == null || alarmHandlerPluginDir == null) {
alarmHandler = new LogAlarmHandler();
} else {
try {
File externalLibDir = new File(alarmHandlerPluginDir);
File[] jarFiles = externalLibDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
});
if (jarFiles == null || jarFiles.length == 0) {
throw new IllegalStateException(String.format("alarmHandlerPluginDir [%s] can't find any name endswith \".jar\" file.",
alarmHandlerPluginDir));
}
// 获取 对应 jar 里面的文件 并且 转成 url
URL[] urls = new URL[jarFiles.length];
for (int i = 0; i < jarFiles.length; i++) {
urls[i] = jarFiles[i].toURI().toURL();
}
// 类加载器 加载 并且 实例化
ClassLoader currentClassLoader = new URLClassLoader(urls,
CanalInstanceWithManager.class.getClassLoader());
Class<CanalAlarmHandler> _alarmClass = (Class<CanalAlarmHandler>) currentClassLoader.loadClass(alarmHandlerClass);
alarmHandler = _alarmClass.newInstance();
logger.info("init [{}] alarm handler success.", alarmHandlerClass);
} catch (Throwable e) {
String errorMsg = String.format("init alarmHandlerPluginDir [%s] alarm handler [%s] error: %s",
alarmHandlerPluginDir,
alarmHandlerClass,
ExceptionUtils.getFullStackTrace(e));
logger.error(errorMsg);
throw new CanalException(errorMsg, e);
}
}
logger.info("init alarmHandler end! \n\t load CanalAlarmHandler:{} ", alarmHandler.getClass().getName());
}
elk