這聽起來像動態外掛架構:業務邏輯封裝在獨立類別(如 org.com.test.HelloDate),編譯後的 .class 檔或位元組碼存入資料庫 BLOB 欄位,執行時由主程式讀取、實例化並呼叫特定方法完成統計作業。核心關鍵在於 Java 反射 與 自訂 ClassLoader。
byte[] 或直接讀取 .class 檔案流。ClassLoader,覆寫 findClass(String name),將位元組碼轉為 Class 物件。Class.newInstance() 或 Constructor.newInstance() 建立物件,再用 Method.invoke() 呼叫業務方法。// 1. 自訂 ClassLoader 從資料庫載入位元組碼
public class DBClassLoader extends ClassLoader {
private final DataSource ds;
public DBClassLoader(DataSource ds) { this.ds = ds; }
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(
"SELECT class_bytes FROM business_classes WHERE class_name = ?")) {
ps.setString(1, name);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
byte[] bytes = rs.getBytes("class_bytes");
return defineClass(name, bytes, 0, bytes.length);
}
}
} catch (SQLException | IOException e) {
throw new ClassNotFoundException(name, e);
}
throw new ClassNotFoundException(name);
}
}
// 2. 主程式動態載入並執行
public class StatEngine {
public static void main(String[] args) throws Exception {
DataSource ds = ...; // 你的連線池
DBClassLoader loader = new DBClassLoader(ds);
// 載入類別
Class<?> clazz = loader.loadClass("org.com.test.HelloDate");
// 取得預設建構子並實例化
Object instance = clazz.getDeclaredConstructor().newInstance();
// 反射設定屬性(若有 setter)
Method setDate = clazz.getMethod("setDate", String.class);
setDate.invoke(instance, "2024-05-20");
// 呼叫統計方法
Method doStat = clazz.getMethod("executeStat");
Object result = doStat.invoke(instance);
System.out.println("統計結果:" + result);
}
}
資料庫欄位型別建議用 BLOB 或 BYTEA。若類別檔較小(< 64 KB),也可 Base64 編碼存 TEXT,但二進位較高效。
每次業務邏輯更新時,只需替換資料庫中的位元組碼,主程式重新建立 DBClassLoader 即可載入新版本,無需重啟 JVM。注意:同一個 ClassLoader 實例無法重複載入同名類別,必須拋棄舊 Loader 建立新實例。
SecurityManager 或使用沙箱機制限制權限。反射調用拋出的 InvocationTargetException 真正原因在 getCause() 中,務必完整記錄堆疊追蹤以利除錯。
若業務邏輯頻繁變動且非極高效能需求,可考慮:
「把類別存進資料庫再動態載入」本質上是 自訂 ClassLoader + 反射 的經典應用。掌握 defineClass、loadClass、Constructor.newInstance、Method.invoke 四大核心 API,即可構建靈活的外掛/業務引擎架構。記住:類別隔離靠換 ClassLoader,安全靠權限管控,維運靠完善日誌。