您好,登錄后才能下訂單哦!
小編給大家分享一下java實(shí)現(xiàn)動(dòng)態(tài)編譯并動(dòng)態(tài)加載的方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
在D盤test目錄下有個(gè)java文件:AlTest.java
public class AlTest { public String sayHello(){ System.out.println("AlTest類 sayHello()方法正在執(zhí)行...."); return "hello word"; } }
現(xiàn)需要實(shí)現(xiàn)在工程已經(jīng)運(yùn)行過(guò)程中,進(jìn)行java文件到class文件的編譯操作,并運(yùn)行AlTest類的方法
package com.piao.job; import java.lang.reflect.Method; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component @Configurable @EnableScheduling public class CompilerJob { private static final Logger logger = LoggerFactory.getLogger(CompilerJob.class); private static boolean isExecute = false; /** * 任務(wù):job test */ @Scheduled(cron = "*/10 * * * * * ") public void test2() { try { if (isExecute) { return; } isExecute = true; //只是測(cè)試,所以只執(zhí)行一次 complierAndRun(); } catch (Exception e) { logger.error("test", e); } } public void complierAndRun(){ try { System.out.println(System.getProperty("user.dir")); //動(dòng)態(tài)編譯 JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); int status = javac.run(null, null, null, "-d", System.getProperty("user.dir")+"\\target\\classes","D:/test/AlTest.java"); if(status!=0){ System.out.println("沒有編譯成功!"); } //動(dòng)態(tài)執(zhí)行 Class clz = Class.forName("AlTest");//返回與帶有給定字符串名的類 或接口相關(guān)聯(lián)的 Class 對(duì)象。 Object o = clz.newInstance(); Method method = clz.getDeclaredMethod("sayHello");//返回一個(gè) Method 對(duì)象,該對(duì)象反映此 Class 對(duì)象所表示的類或接口的指定已聲明方法 String result= (String)method.invoke(o);//靜態(tài)方法第一個(gè)參數(shù)可為null,第二個(gè)參數(shù)為實(shí)際傳參 System.out.println(result); } catch (Exception e) { logger.error("test", e); } } }
運(yùn)行結(jié)果:
E:\zhoufy\small\piao-admin
AlTest類 sayHello()方法正在執(zhí)行....
hello word
其中代碼:
int status = javac.run(null, null, null, "-d", System.getProperty("user.dir")+"\\target\\classes","D:/test/AlTest.java");
把class文件生成到了當(dāng)前工程目錄下的classes目錄(E:\zhoufy\small\piao-admin\target\classess)所以classloader是可以加載到的,如果想知道是哪個(gè)類加載器:
Class clz = Class.forName("AlTest");//返回與帶有給定字符串名的類 或接口相關(guān)聯(lián)的 Class 對(duì)象。
Object o = clz.newInstance();
System.out.println(clz.getClassLoader().getSystemClassLoader());
打印的是: sun.misc.Launcher$AppClassLoader@4e0e2f2a 說(shuō)明使用的是AppClassLoader
當(dāng)然也可以生成到Bootstrap ClassLoader可加載的目錄下
//生成到工程classes下 //int status = javac.run(null, null, null, "-d", System.getProperty("user.dir")+"\\target\\classes","D:/test/AlTest.java"); //生成到BootStrap ClassLoader可加載目錄下 int status = javac.run(null, null, null, "-d", "C:\\Program Files\\Java\\jdk1.8.0_65\\jre\\classes","D:/test/AlTest.java");
當(dāng)然也可以自定義類加載器,把文件生成在指定的外部目錄 :
public void complierAndRun(){ try { System.out.println(System.getProperty("user.dir")); //動(dòng)態(tài)編譯 JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); int status = javac.run(null, null, null, "-d", "D:\\","D:/test/AlTest.java"); if(status!=0){ System.out.println("沒有編譯成功!"); } //動(dòng)態(tài)執(zhí)行 //Class clz = Class.forName("AlTest");//返回與帶有給定字符串名的類 或接口相關(guān)聯(lián)的 Class 對(duì)象。 //自定義類加載器的加載路徑 MyClassLoader myClassLoader = new MyClassLoader("D:\\"); //包名+類名 Class clz = myClassLoader.loadClass("AlTest"); Object o = clz.newInstance(); Method method = clz.getDeclaredMethod("sayHello");//返回一個(gè) Method 對(duì)象,該對(duì)象反映此 Class 對(duì)象所表示的類或接口的指定已聲明方法 String result= (String)method.invoke(o);//靜態(tài)方法第一個(gè)參數(shù)可為null,第二個(gè)參數(shù)為實(shí)際傳參 System.out.println(result); } catch (Exception e) { logger.error("test", e); } }
java動(dòng)態(tài)執(zhí)行代碼的代碼, java eval
public class ScriptUtils { private static final Logger logger = LoggerFactory.getLogger(ScriptUtils.class); /** * * <p>執(zhí)行字符串計(jì)算</p> * @param express * @param params * @return * @throws ScriptException */ @SuppressWarnings("unchecked") public static <T, E> E eval(String express, Map<String, T> params) throws ScriptException{ ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); if(params == null){ params = new HashMap<String,T>(); } Iterator<Map.Entry<String, T>> iter = params.entrySet().iterator(); Map.Entry<String, T> entry = null; while(iter.hasNext()){ entry = iter.next(); engine.put(entry.getKey(), entry.getValue()); } E result = null; try { result = (E)engine.eval(express); } catch (ScriptException e) { logger.warn("表達(dá)式執(zhí)行異常: " + e.getMessage()); } return result; } /** * 解析字符串, 并將其當(dāng)作表達(dá)式執(zhí)行 * @param express * @param params * @return * @throws ScriptException */ public static <T> Boolean evalBoolean(String express, Map<String, T> params) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); if(params == null){ params = new HashMap<String,T>(); } Iterator<Map.Entry<String, T>> iter = params.entrySet().iterator(); Map.Entry<String, T> entry = null; while(iter.hasNext()){ entry = iter.next(); engine.put(entry.getKey(), entry.getValue()); } Boolean result = null; try { result = (Boolean)engine.eval(express); } catch (ScriptException e) { result = false; logger.warn("表達(dá)式執(zhí)行異常: " + e.getMessage()); } return result; }
以上是“java實(shí)現(xiàn)動(dòng)態(tài)編譯并動(dòng)態(tài)加載的方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。