classloader實戰:如何不重啟校驗資料庫驅動連結
場景介紹
使用過was的時候,我們常見的建立資料來源時有一個驗證資料庫資訊的正確性的按鈕。但是如果沒有相應的驅動包的時候,校驗是失敗的,如果想校驗成功,那就加入對應的資料庫驅動包即可,但是was本身並不是熱部署的,要想驗證那就必須重啟was。這個在伺服器還是可以接受的,因為你建立資料來源肯定是是先有規劃的,驅動包都是放入指定地點的,weblogic11g was本身還提供了很多資料庫的Jar包以備使用。但是換成一個配置系統的話,那這樣的操作就不能忍受了。因為要驗證一下資料庫連線是否正確還要去重啟遠端的機器,這聽起來就比較麻煩。
解決方案
java的熱部署方案可以解決這個問題。java利用classloader的雙親委託機制可以解決這個問題。思路就是用新的classloader去載入類,然後去做校驗,打破雙親委託。類載入的目錄就是我們指定的目錄,每次可以上傳jar包到固定目錄。然後用新的classloader去載入。
程式碼實現
首先要寫一個破壞雙親委託的classloader。
package com.xp.classloader;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
public class DriverLoader extends URLClassLoader {
// class cache
Map<String, Class<?>> loadedClasses = new HashMap<>();
public DriverLoader(URL[] urls) {
super(urls);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (loadedClasses.containsKey(name)) {
return loadedClasses.get(name);
}
try {
Class<?> findClass = this.findClass(name);
loadedClasses.put(name, findClass);
return findClass;
} catch (ClassNotFoundException e) {
// ignore it
}
return super.loadClass(name);
}
@Override
protected Package getPackage(String name) {
return super.getPackage(name);
}
}
當有新的jar包上傳的時候,就需要重新載入類,這裡的類是可以配置的。然後根據配置讀取載入的類。
package com.xp.classloader;
import java.io.File;
import java.io.FilenameFilter;
import java.net.URL;
public class ClassManager {
public static final String DIR = "d:/jarFile/";
public static Class<?> getClass(String className) throws Exception {
File jarDir = new File(DIR);
File[] listFiles = jarDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// check jar file
if (name.endsWith(".jar")) {
return true;
}
return false;
}
});
URL[] urls;
if (listFiles == null) {
urls = new URL[0];
} else {
int count = 0;
urls = new URL[listFiles.length];
for (File listFile : listFiles) {
urls[count++] = listFile.toURI().toURL();
}
}
ClassLoader loader = new DriverLoader(urls);
return loader.loadClass(className);
}
}
為了發現檔案上傳就可以出發這個操作,所以此時需要使用java7的新特性---目錄監控。
package com.xp.dir;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
public class DirWatcher {
private WatchService service;
public DirWatcher(String filePath) throws IOException {
service = FileSystems.getDefault().newWatchService();
// register create event
Paths.get(filePath).register(service, StandardWatchEventKinds.ENTRY_CREATE);
}
public void watch(WatcherHandler handler) throws InterruptedException {
while (true) {
WatchKey key = service.take();
for (WatchEvent<?> event : key.pollEvents()) {
Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
handler.handler();
}
}
key.reset();
}
}
}
為了完成功能程式碼簡潔,這裡使用了回撥。增加一個介面。
package com.xp.dir;
public interface WatcherHandler {
public void handler();
}
接下來就是呼叫的主體。
package com.xp;
import com.xp.classloader.ClassManager;
import com.xp.dir.DirWatcher;
import com.xp.dir.WatcherHandler;
public class Main {
public static void main(String[] args) throws Exception {
new DirWatcher(ClassManager.DIR).watch(new WatcherHandler() {
@Override
public void handler() {
Class<?> class1;
try {
class1 = ClassManager.getClass("com.mysql.jdbc.Driver");
if (class1 != null) {
System.out.println("success");
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
開啟目錄監控,然後直接使用回撥去載入mysql的驅動類。這裡已經獲取到驅動類了,再通過這個驅動類就能直接獲取連結。
總結
classloader讓Java的操作更加靈活,很多需要重啟應用的問題,都可以考慮加入classloader來做到熱更新。
相關文章
- MySQL手動資料校驗+雲資料庫資料校驗MySql資料庫
- Dolphinscheduler不重啟載入Oracle驅動Oracle
- MySQL資料庫如何啟動?MySql資料庫
- DBeave如何連線達夢資料庫,設定達夢驅動,真酷資料庫
- Mybatis資料庫驅動MyBatis資料庫
- spring boot 不連線資料庫啟動Spring Boot資料庫
- 資料結構實驗之連結串列二:逆序建立連結串列資料結構
- 資料結構實驗之連結串列九:雙向連結串列資料結構
- 資料結構實驗:連結串列的應用資料結構
- 資料結構實驗之連結串列三:連結串列的逆置資料結構
- 資料結構實驗之連結串列五:單連結串列的拆分資料結構
- 資料結構實驗之連結串列六:有序連結串列的建立資料結構
- 資料結構實驗之連結串列一:順序建立連結串列資料結構
- php連結資料庫PHP資料庫
- JDBC連結資料庫JDBC資料庫
- 資料校驗
- 資料結構實驗之連結串列八:Farey序列資料結構
- 介面平臺實用功能設計分享——資料庫校驗資料庫
- 資料庫實驗室挑戰任務-2資料庫
- Angular如何在模板驅動表單中自定義校驗器Angular
- 探索資料結構:單連結串列的實戰指南資料結構
- 資料結構實驗之連結串列四:有序連結串列的歸併資料結構
- mongodb資料庫連結失敗如何解決MongoDB資料庫
- 談談如何建立價值驅動的資料戰略
- 實戰PHP資料結構基礎之單連結串列PHP資料結構
- 實戰PHP資料結構基礎之雙連結串列PHP資料結構
- jmeter連結mysql資料庫JMeterMySql資料庫
- [資料校驗/資料質量] 資料校驗框架(Java):hibernate-validation框架Java
- easypoi資料校驗
- WPF 資料繫結之ValidationRule資料校驗綜合Demo
- 資料庫實驗二資料庫
- Go實戰準備工作---建立資料庫連線池Go資料庫
- cmake 連結動態連結庫
- .NET中特性+反射 實現資料校驗反射
- 3.1 啟動資料庫資料庫
- 啟動MySql資料庫MySql資料庫
- 鋪貼如何校驗?酷家樂硬裝鋪貼 UI 自動化實戰UI
- springboot的服務不需要連線資料庫,如何保證正常啟動Spring Boot資料庫