• Tomcat解析XML和反射创建对象原理


    Tomcat解析XML和反射创建对象原理

      1 import java.lang.reflect.InvocationTargetException;
      2 import java.lang.reflect.Method;
      3 import java.util.List;
      4 
      5 import org.dom4j.Document;
      6 import org.dom4j.DocumentException;
      7 import org.dom4j.Element;
      8 import org.dom4j.io.SAXReader;
      9 
     10 public class ServerReadXML1 {
     11 
     12     public static void main(String[] args)
     13             throws DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException,
     14             NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
     15 
     16         // 现在假如在浏览器中输入一个Servlet的url-pattern
     17         String urlPattern = "/first";
     18 
     19         // 根据urlPattern 获取类名
     20         String className = getClassByUrl(urlPattern);
     21 
     22         // 根据全类名获取Class对象
     23         Class clazz = Class.forName(className);
     24 
     25         // 通过反射clazz对象创建指定对象
     26         Object obj = clazz.newInstance();
     27 
     28         // 获取service方法
     29         Method method = clazz.getDeclaredMethod("service");
     30 
     31         // 获取权限
     32         method.setAccessible(true);
     33 
     34         // 执行service方法
     35         method.invoke(obj);
     36 
     37     }
     38 
     39     private static String getClassByUrl(String urlPattern) throws DocumentException {
     40 
     41         // 1.创建SAXReader对象
     42         SAXReader reader = new SAXReader();
     43 
     44         // 2.读取文件
     45         Document document = reader.read(ServerReadXML1.class.getClassLoader().getResourceAsStream("web.xml"));
     46 
     47         // 3.获取根节点
     48         Element rootElement = document.getRootElement();
     49         //System.out.println(rootElement.getName());
     50 
     51         // 4.获取根节点下 的子节点
     52         List<Element> servletList = rootElement.elements();
     53 
     54         // 记录与urlPattern相同的servlet-name标签的内容
     55         String servletName = "";
     56 
     57         // 记录servlet标签中的servlet-class的内容
     58         // servletClassName的内容也就是Servlet的全类名
     59         String servletClassName = "";
     60 
     61         // 5.遍历子节点
     62         for (Element servletElement : servletList) {
     63             //System.out.println(servletElement.getName());
     64 
     65             // 判断如果是servlet-mapping标签时,执行代码
     66             if ("servlet-mapping".equals(servletElement.getName())) {
     67 
     68                 // 获取url-pattern标签对象
     69                 Element url = servletElement.element("url-pattern");
     70 
     71                 // 判断标签的内容和入的urlPattern值是否相同
     72                 if (urlPattern.equals(url.getText())) {
     73 
     74                     // 记录与urlPattern相同的servlet-name标签的内容
     75                     // 如果相同,则记录ServletName
     76                     // 获取servlet-mapping中的servelt-name的内容
     77                     servletName = servletElement.element("servlet-name").getText();
     78 
     79                 }
     80 
     81             }
     82 
     83         }
     84 
     85         // 再次遍历
     86         for (Element servletElement : servletList) {
     87             // 判断如果是servlet标签时,执行此代码
     88             if ("servlet".equals(servletElement.getName())) {
     89 
     90                 // 判断上一次的遍历获取的servletName的值和这次遍历中的servlet-name的内容是否相同
     91                 if (servletName.equals(servletElement.element("servlet-name").getText())) {
     92 
     93                     // 如果相同记录servletClassName
     94                     servletClassName = servletElement.element("servlet-class").getText();
     95 
     96                 }
     97 
     98             }
     99 
    100         }
    101 
    102         // 返回Servlet的全类名 servletClassName
    103         return servletClassName;
    104     }
    105 
    106 }

    1.反射的获取Class 4种方式

    @Test
        public void test1() throws ClassNotFoundException {
            
            //1.类名.class
            Class clazz = String.class;
            System.out.println(clazz);
            
            //2.对象.getClass()
            Class clazz1 = "abc".getClass();
            System.out.println(clazz1);
            
            //3.Class.forName();
            Class clazz2 = Class.forName("java.lang.String");
            System.out.println(clazz2);
            
            //4.ClassLoader .loadClass("全类名")
            Class clazz3 = ReflectTest1.class.getClassLoader().loadClass("java.lang.String");
            System.out.println(clazz3);
            
            
        }

    2.反射使用属性的常用方法

    @Test
        public void test2() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
            
            //获取Class对象 可以获取其内部的属性
            Class clazz = Class.forName("com.atguigu.bean.User");
            
            User user = new User();
            
            //Field对象 代表中类的属性 getField只能获取公共属性
            Field field = clazz.getField("email");
            System.out.println(field);
            
            
             //此种方式破坏代码的封装性 不推荐使用
            Field field2 = clazz.getDeclaredField("id");
            System.out.println(field2);
            
            field2.setAccessible(true);
            field2.setInt(user, 1001);
            System.out.println(user);
            
            
        }

    3.反射使用方法的常用方法

    @Test
        public void test3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
            
            Class clazz = Class.forName("com.atguigu.bean.User");
            
            //通过反射创建对象
            Object obj = clazz.newInstance();
            
            //现在想要设置name值
            String fileName = "name";
            
            //创建一个方法名
            String methodName = "set" + fileName.substring(0, 1).toUpperCase() //N
            + fileName.substring(1).toLowerCase(); //ame
            
            //根据方法名 获取公共方法
            Method method = clazz.getMethod(methodName, String.class);
            
            //执行指定的方法
            method.invoke(obj, "yangjian");
            
            
            System.out.println(obj);
        }
  • 相关阅读:
    Squeeze-and-Attention Networks for Semantic Segmentation
    重装电脑系统(用山寨优盘)
    TensorFlow会话常用的两种方式
    Towards Learning Structure via Consensus for Face Segmentation and Parsing
    什么是feature map(个人理解)
    Fatal error in launcher: Unable to create process using '"d:downloadpython.exe" "D:downloadScriptspip.exe" list': ???????????
    JS :函数
    JS之继承
    原型模式
    面向对象之工厂模式和构造函数模式
  • 原文地址:https://www.cnblogs.com/zmy-520131499/p/11319482.html
Copyright © 2020-2023  润新知