標籤:這一 title dog otf build tle alac ges ring
個人部落格地址:http://www.cnblogs.com/wdfwolf3/。轉載註明出處,謝謝。
Java 反射一個是可以擷取程式在運行時刻的內部結構,二是在運行時刻對一個Java對象進行操作。主要用途有以下幾點:
1.原廠模式:Factory類中用反射的話,添加了一個新的類之後,就不需要再修改工廠類Factory了
2.資料庫JDBC中通過Class.forName(Driver)來獲得資料庫連接驅動
3.分析類檔案:得到類中的方法等等,訪問一些不能訪問的變數或屬性(破解別人代碼)。
之前學習了反射的一些知識,這裡針對第二個功能寫一個小demo,試一下不停止tomcat的運行(即在web服務啟動以後不重啟服務),將新的的類放入服務中,並能夠成功載入使用。這裡只是為了測試反射,對於功能和web的搭建都很簡單。直接上原始碼,不難理解,後面主要講一下操作過程。
項目結構如下,使用idea+maven+servlet+tomcat
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <!-- 這裡名稱隨意,因為打成war包放進tomcat,訪問url路徑與這裡的名字沒有關係。 --> <servlet-name>HttpRequest</servlet-name> <!--用來指定servlet的實作類別--> <servlet-class>com.wdf.HttpRequest</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <!-- 名稱需與servlet裡的name一致 --> <servlet-name>HttpRequest</servlet-name> <!-- 頁面中調用servlet類時,名稱可以任意取,但是需要/ --> <url-pattern>/my</url-pattern> </servlet-mapping></web-app>
DynamicOne.java和DynamicTwo.java兩個類都是建立的空類,不需要實現什麼方法。HttpRequest.java為HttpServlet繼承類,如下
package com.wdf;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class HttpRequest extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //classname.txt中存放待載入的類名,這個也可以放在資料庫中測試,每次查詢出來。只是懶得寫jdbc了。 BufferedReader bufferedReader = new BufferedReader(new FileReader("classname.txt檔案相對路徑")); String className = null; List<String> list = new ArrayList<>(); //檔案中每行一個類名,按行讀取載入,然後將類名放入list待網頁顯示。 while ((className = bufferedReader.readLine()) != null) { Class c = Class.forName(className); Object object = c.newInstance(); list.add(className); } PrintWriter printWriter = response.getWriter(); printWriter.println("<html><title></title><body>" + Arrays.toString(list.toArray()) + "</body></html>"); printWriter.flush(); printWriter.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } }}
classname.txt存放類名,放入本地某個位置待函數調用。
com.wdf.reflect.DynamicOnecom.wdf.reflect.DynamicTwo
代碼就是這些,然後通過maven project下的package將項目打成war包,放入tomcat的webapps目錄下。這裡不用maven或者不用idea都無所謂,就是打成war包即可。war包名稱是reflect.war(預設項目名稱.war)。這個名稱是url的根路徑,即127.0.0.1:8080/reflect,然後加上web.xml中<servlet-mapping>設定的/my,就是訪問的我們寫的HttpRequest類。可以看到頁面上顯示[com.wdf.reflect.DynamicOne, com.wdf.reflect.DynamicTwo],正是我們預期的。
然後我們在com.wdf.reflect包下建立一個DynamicThree類,並build成class檔案,將這個檔案放入webapps/reflect/WEB-INF/classes/com/wdf/reflect/下面,因為這裡就是tomcat啟動後解析war包,得到class檔案後的存放位置,放入正確的包位置中才可以正確的找到。然後修改一下classname.txt檔案,加入一行com.wdf.reflect.DynamicThree,這樣函數可以讀取到這一行,得到這個類名,然後去載入DynamicThree.class。這兩步完成後重新整理頁面,看到如下,說明成功載入。
整個過程不需要停止tomcat,利用反射,實現了新增類的載入。反射的另一個功能就是完成載入類之後的具體使用。
利用java反射實現tomcat運行中添加新類