我的博客地址:http://www.cnblogs.com/wdfwolf3/。转载注明出处,谢谢。html
Java 反射一个是能够获取程序在运行时刻的内部结构,二是在运行时刻对一个Java对象进行操做。主要用途有如下几点:java
1.工厂模式:Factory类中用反射的话,添加了一个新的类以后,就不须要再修改工厂类Factory了web
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,利用反射,实现了新增类的加载。反射的另外一个功能就是完成加载类以后的具体使用。