• 利用java反射实现tomcat运行中添加新类


    个人博客地址: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.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,利用反射,实现了新增类的加载。反射的另一个功能就是完成加载类之后的具体使用。
  • 相关阅读:
    Docker常用命令总结(不断更新)
    Docker容器简介-与虚拟机的区别及安装步骤
    ELK搭建—安装使用Kibana可视化
    使用CURL与ElasticSearch服务进行通信
    安装部署ElasticSearch单节点在Linux服务器上
    ElasticStack分布式引擎技术栈(ELK)介绍
    为Nginx服务器配置黑(白)名单的防火墙
    php大力力 [026节] php开发状态要随时做好整理工作
    php大力力 [025节] 来不及学习和分类的,大力力认为有价值的一些技术文章合集(大力力二叔公)(2015-08-27)
    php大力力 [024节]PHP中的字符串连接操作(2015-08-27)
  • 原文地址:https://www.cnblogs.com/wdfwolf3/p/7423436.html
Copyright © 2020-2023  润新知