動態加載jar,實現自定義業務
阿新 • • 發佈:2018-06-07
讀取 bool AR sta instance snapshot pub 加載 set
在實際業務中,我們經常會遇到需要按不同用戶實現不同業務邏輯,如果按照最簡單粗暴的做法,當然是使用if else ...來實現。
不過作為一個社會人,這樣怎麽能體現出我們的戰鬥力呢,下面我們來實現一個牛叉的方法。
具體思路:
將不同的業務邏輯按用戶放到不同的jar包,然後系統通過讀取jar包,來實現各自業務;
以後即使用戶的邏輯發生變化,也只要把jar包上傳到服務器,就可以動態實現,不影響生產環境了。
1.接口
public interface InterfaceAction { public String getId(); public abstractString action(); }
2.新建項目
action.ext.bj
pom.xml 依賴於base包
<dependency> <groupId>com.qn</groupId> <artifactId>action.base</artifactId> <version>0.0.1-SNAPSHOT</version>
</dependency>
實現接口
public class ExtBj implementsInterfaceAction { /** * @see action.base.code.InterfaceAction#getId() */ @Override public String getId() { return "bj"; } /** * @see action.base.code.InterfaceAction#action() */ @Override public String action() { return "This is bj...."; } }
按照此項目新建個action.ext.nt
實現完接口後,導出jar包,存放到一個目錄下;
3.完成自定義MyClassLoader
public class MyClassLoader { private ClassLoader loader; private Map<String, InterfaceAction> actionMap = new HashMap<>(); /** * Getter method for property <tt>actionMap</tt>. * * @return property value of actionMap */ public Map<String, InterfaceAction> getActionMap() { return actionMap; } /** * Setter method for property <tt>actionMap</tt>. * * @param actionMap value to be assigned to property actionMap */ public void setActionMap(Map<String, InterfaceAction> actionMap) { this.actionMap = actionMap; } public void load(String jarFileName) { JarFile jarFile = null; try { File file = new File(jarFileName); URL url = new URL("file:" + jarFileName); loader = new URLClassLoader(new URL[] { url }); file.lastModified(); jarFile = new JarFile(file); Enumeration<JarEntry> enumFiles = jarFile.entries(); JarEntry entry; //遍歷Jar包中的每一個文件 while (enumFiles.hasMoreElements()) { entry = enumFiles.nextElement(); String classFullName = entry.getName(); //僅處理.class文件 if (classFullName.indexOf("META-INF") < 0 && classFullName.indexOf(".class") > 0) { String className = classFullName.substring(0, classFullName.length() - 6) .replaceAll("/", "."); //使用當前類加載器加載jar包中的類 System.out.println("加載類start:" + className); Class<?> clazz = loader.loadClass(className); System.out.println("加載類end:" + clazz); boolean flag = isInterface(clazz, InterfaceAction.class); if (flag) { InterfaceAction ia = ((Class<InterfaceAction>) clazz).newInstance(); actionMap.put(ia.getId(), ia); System.out.println(actionMap); } } } } catch (Exception e) { e.printStackTrace(); } } /** * 是否實現該接口 * @param c * @param szInterface * @return */ private boolean isInterface(Class c, Class szInterface) { Class[] face = c.getInterfaces(); for (int i = 0, j = face.length; i < j; i++) { if (face[i].equals(szInterface)) { return true; } } return false; } }
4.接下來就是test了
public static void main(String[] args) { MyClassLoader ml = new MyClassLoader(); ml.load("D:\\temp\\action.ext.bj.jar"); ml.load("D:\\temp\\action.ext.nt.jar"); String s = ml.getActionMap().get("nt").action(); System.out.println(s); }
加載類start:action.ext.bj.ExtBj 加載類end:class action.ext.bj.ExtBj {bj=action.ext.bj.ExtBj@5cd73256} 加載類start:action.ext.nt.ExtNt 加載類end:class action.ext.nt.ExtNt {nt=action.ext.nt.ExtNt@6f580c3a, bj=action.ext.bj.ExtBj@5cd73256} This is nt.....
韋爵爺說過:大功告成。。。
動態加載jar,實現自定義業務