利用java反射實現tomcat運行中添加新類

我的博客地址:http://www.cnblogs.com/wdfwolf3/。轉載註明出處,謝謝。html

  Java 反射一個是能夠獲取程序在運行時刻的內部結構,二是在運行時刻對一個Java對象進行操做。主要用途有如下幾點:java

1.工廠模式:Factory類中用反射的話,添加了一個新的類以後,就不須要再修改工廠類Factoryweb

2.數據庫JDBC中經過Class.forName(Driver)來得到數據庫鏈接驅動數據庫

3.分析類文件:獲得類中的方法等等訪問一些不能訪問的變量或屬性(破解別人代碼)。tomcat

  以前學習了反射的一些知識,這裏針對第二個功能寫一個小demo,試一下不中止tomcat的運行(即在web服務啓動之後不重啓服務),將新的的類放入服務中,並可以成功加載使用。這裏只是爲了測試反射,對於功能和web的搭建都很簡單。直接上源代碼,不難理解,後面主要講一下操做過程。app

項目結構以下,使用idea+maven+servlet+tomcatwebapp

web.xmlmaven

<?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繼承類,以下ide

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.DynamicOne
com.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,利用反射,實現了新增類的加載。反射的另外一個功能就是完成加載類以後的具體使用。
相關文章
相關標籤/搜索