zoukankan      html  css  js  c++  java
  • 手动添加Servlet构造函数出现的问题及猜想

    我们需要用到servlet的时候,都是右键,新建一个servlet,但是有人注意到一个细节没有,当我们手动给我们的servlet添加一个构造函数时候,会出现什么状况呢?

    1.尝试添加无参构造函数


    直接上代码

    public class Test extends HttpServlet {
    
        Test(){
            System.out.println("这是构造函数");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        }
    }

    好了,一个我们都熟悉的基本的servlet,它的名字叫做Test。

    为了方便起见,我们重写接口Servlet中的init()函数,并配置这个Servlet预加载,更直观的帮助我们理解。

    public class Test extends HttpServlet {
    Test(){ System.out.println("这是构造函数"); }
    @Override
    public void init() throws ServletException { System.out.println("这是Init函数"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }

    好了,关于预加载,简单说,就是服务器运行的的时候,就会实例化这个servlet并且走完init()函数,这样,我们只需开启服务器,不需要进行请求,就可以看出这个servlet'是否被正确实例化。

     

    好了,测试开始,启动服务器。

    实验结果:手动写的Test()构造函数没有被执行,init()函数也没被执行。浏览器访问此Servlet时,404错误。

    实验结论:当我们手动一个无参Servlet构造函数时,服务器就不会创建我们请求的servlet实例,当然也不会走servlet的生命周期

    2.尝试有参构造函数

    public class Test extends HttpServlet {
    
        Test(String a){
            System.out.println("这是构造函数");
        }
    
        @Override
        public void init() throws ServletException {
            System.out.println("这是Init函数");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        }
    }

    结果同无参构造函数一样:服务器不会创建servlet实例。

    3.web.xml给出错误提示

    错误说,我们的servlet没有默认的构造函数。

    我们现在证明了,手动写一个有参和无参构造函数后,服务器都不会创建这个实例,根据xml错误,我们保留默认无参构造函数,并重载一个有参构造函数

    public class Test extends HttpServlet {
    
        Test(){}
    
        Test(String a){
            System.out.println("这是构造函数");
        }
    
        @Override
        public void init() throws ServletException {
            System.out.println("这是Init函数");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        }
    }

    实验结果:构造函数仍无法输出任何内容,init()方法也不输出,说明servlet仍未被创建实例。

    4.结果猜想:我们都知道,当我们请求servlet时候,服务器会根据servlet的servlet-class,反射创建servlet对象,并且会将一些参数传入到实例中(例如request,response,servletConfig等),

    大致流程就是Class.from("我们的servlet-class").getDeclaredConstructor(上述说的参数类型...).newInstance(上述说的参数的值...)

    因为,只有这样构造实例,才能把一些必要的数据(request,response,servletConfig),封装到实例里面。

    况且,这个有参构造函数,第一句又调用了无参构造函数,也就是 this();

    这样,通过有参构造函数将参数传递过来并保存,然后在无参构造函数中,进行初始化servlet,因此,当我们重写了无参构造,服务器就无法完成这些流程,因此,服务器直接做一个判断,如果你手动写了构造函数,直接让这个servlet无法初始化。

  • 相关阅读:
    tcpdump命令
    浅谈  curl命令
    MongoDB下rs.status()命令
    Device mapper存储方式
    top命令
    cat命令汇总整理
    centos7搭建nginx日志
    CentOS7 防火墙(firewall)的操作命令(转)
    服务器的硬件组成
    shell随机生成10个文件
  • 原文地址:https://www.cnblogs.com/zh1996/p/10353351.html
Copyright © 2011-2022 走看看