diff --git a/README.md b/README.md index 27db2c9..6d53c55 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,15 @@ 特定驱动的ClassLoader拦截器demo -05-20:demo需要依赖最新release分支的datasource模块 \ No newline at end of file +使用方法: + + 该插件是用于隔离数据库JDBC的驱动jar包,从而避免驱动jar引入的jar包冲突问题 + + 启用该插件以后,需要在WEB-INF目录下新建一个driverlib文件夹,将对应的驱动jar包放入这个文件夹内即可 + + 注意:使用了隔离插件以后驱动jar包不需要放在lib目录下 + + 目前该插件默认是隔离MySQL的驱动,如果是其他数据源,只需要修改DRIVER_NAME_KEY为对应的驱动即可 + +PS:demo需要依赖最新release分支的datasource模块 + diff --git a/plugin.xml b/plugin.xml index a384dbd..08a383f 100644 --- a/plugin.xml +++ b/plugin.xml @@ -10,6 +10,7 @@ [2019-05-20]优化逻辑。
+ [2019-05-30]实现一个可用的ClassLoader。
]]>
com.fr.plugin.dialect.classloader diff --git a/src/main/java/com/fr/plugin/dialect/classloader/ClassLoaderHandler.java b/src/main/java/com/fr/plugin/dialect/classloader/ClassLoaderHandler.java index 837256b..8a8e957 100644 --- a/src/main/java/com/fr/plugin/dialect/classloader/ClassLoaderHandler.java +++ b/src/main/java/com/fr/plugin/dialect/classloader/ClassLoaderHandler.java @@ -3,26 +3,36 @@ package com.fr.plugin.dialect.classloader; import com.fr.intelli.record.Focus; import com.fr.intelli.record.Original; +import com.fr.io.utils.ResourceIOUtils; import com.fr.log.FineLoggerFactory; import com.fr.record.analyzer.EnableMetrics; import com.fr.stable.fun.impl.AbstractDataSourceDriverLoader; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + /** * Created by Munin on 2019/5/20 */ @EnableMetrics public class ClassLoaderHandler extends AbstractDataSourceDriverLoader { + //插件获取jar的路径,和lib同级的driverlib目录 + public static final String DRIVER_LIB_DIR = "driverlib"; //demo设置为mysql为目标驱动 - private static final String MYSQL_KEY = "com.mysql.jdbc.Driver"; + private static final String DRIVER_NAME_KEY = "com.mysql.jdbc.Driver"; @Focus(id = "com.fr.plugin.dialect.classloader.ClassLoaderHandler", text = "", source = Original.PLUGIN) public boolean isInterceptAllowed(String driverName) { if (driverName == null) { FineLoggerFactory.getLogger().error("error driver name"); + return false; } - if (driverName.compareTo(MYSQL_KEY) == 0) { + if (driverName.equals(DRIVER_NAME_KEY)) { FineLoggerFactory.getLogger().info("correct driver name"); return true; } @@ -32,7 +42,33 @@ public class ClassLoaderHandler extends AbstractDataSourceDriverLoader { @Focus(id = "com.fr.plugin.dialect.classloader.ClassLoaderHandler", text = "", source = Original.PLUGIN) public ClassLoader getClassLoader() { FineLoggerFactory.getLogger().info("====== Loading Mysql ClassLoader ... ======"); - //具体实现可以自定义,这里就直接返回一个null - return null; + URL[] urls = getJarURLS(); + ClassLoader cl = new DriverClassLoader(urls); + Thread.currentThread().setContextClassLoader(cl); + return cl; + } + + + public URL[] getJarURLS() { + List libUrls = new ArrayList(); + try { + + String dir = ResourceIOUtils.getRealPath(DRIVER_LIB_DIR); + File parentDir = new File(dir); + File[] files = parentDir.listFiles(); + if (files != null) { + for (File file : files) { + try { + libUrls.add(file.toURI().toURL()); + } catch (MalformedURLException e) { + FineLoggerFactory.getLogger().warn("get JAR URLS error, the driver lib path is:{}", dir); + } + + } + } + } catch (Exception e) { + } + + return libUrls.toArray(new URL[0]); } } diff --git a/src/main/java/com/fr/plugin/dialect/classloader/DriverClassLoader.java b/src/main/java/com/fr/plugin/dialect/classloader/DriverClassLoader.java new file mode 100644 index 0000000..6f80d96 --- /dev/null +++ b/src/main/java/com/fr/plugin/dialect/classloader/DriverClassLoader.java @@ -0,0 +1,58 @@ +package com.fr.plugin.dialect.classloader; + +import com.fr.log.FineLoggerFactory; + +import java.net.URL; +import java.net.URLClassLoader; + +/** + * @author: Roy + * @date: 2019/5/29 6:39 PM + */ +public class DriverClassLoader extends URLClassLoader { + + public DriverClassLoader(URL[] urls) { + super(urls, Thread.currentThread().getContextClassLoader()); + } + + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + synchronized (getClassLoadingLock(name)) { + Class c = findLoadedClass(name); + if (c == null) { + try { + c = findClass(name); + FineLoggerFactory.getLogger().debug("load class {} from driverlib successful", name); + } catch (Exception e) { + //can not find class in isolate dir, try to load from common lib + } + } + + if (c == null) { + FineLoggerFactory.getLogger().debug("Did not find class{}, in the paths {}, try to get from common lib", name, this.getUrlStrings()); + c = super.loadClass(name); + } + + return c; + } + + } + + private String getUrlStrings() { + StringBuilder stringBuilder = new StringBuilder(); + try { + + for (URL url : getURLs()) { + stringBuilder + .append("\n\r") + .append(url.getPath()) + .append("\n\r"); + } + + } catch (Exception e) { + + } + return stringBuilder.toString(); + } +}