为什么我们不能使用构造函数本身初始化servlet?

时间:2010-05-27 11:24:36

标签: java servlets java-ee initialization

为什么我们必须覆盖Servlet中的init()方法,同时我们可以在构造函数中进行初始化并让web容器调用构造函数,同时调用构造函数将ServletConfig引用传递给servlet?

Ofcourse容器必须使用反射,但容器必须使用反射来调用一个简单的无参数构造函数

5 个答案:

答案 0 :(得分:14)

由于构造函数不能成为接口的一部分,因此与常规方法不同,它不能在Servlet API中“正式”指定。此外,由于Java没有析构函数,因此无论如何都需要destroy方法,因此定义相应的init方法会使API更加一致且更易于使用。

使用反射来检测/验证构造函数参数会使事情变得不必要,并且我没有看到任何附加值。

答案 1 :(得分:5)

Servlet对象具有明确定义的生命周期,其中创建和初始化步骤是不同的。通常,您不希望在构造函数中执行繁重且不可靠的工作,例如获取数据库连接池或初始化缓存。成功创建Servlet对象后,您有机会完成此操作。

此外,http://oreilly.com/catalog/jservlet/chapter/ch03.html是历史原因:

  

init()方法通常用于执行servlet初始化 - 创建或   加载servlet在处理其请求时使用的对象。 为什么不使用构造函数呢?那么,在JDK 1.0(最初编写servlet)中,动态加载的Java类(如servlet)的构造函数不能接受参数。

     

因此,为了向新的servlet提供有关其自身及其环境的任何信息,服务器必须调用servlet的init()方法并传递实现ServletConfig接口的对象。

     

此外,Java不允许接口声明构造函数。这意味着javax.servlet.Servlet接口不能声明接受ServletConfig参数的构造函数。它必须声明另一个方法,如init()。当然,您仍然可以为servlet定义构造函数,但在构造函数中,您无权访问ServletConfig对象或抛出ServletException的能力。

答案 2 :(得分:2)

一个原因是您无法访问构造函数中的ServletConfig对象。在调用构造函数之后创建ServletConfig对象,并在调用 init()之前创建。因此,您无法在构造函数中访问servlet init参数。

答案 3 :(得分:1)

Servlet实现类可以有构造函数但是它们应该使用init()方法来初始化Servlet,原因有两个:首先你不能在Java中的接口上声明构造函数,这意味着你不能对实现Servlet接口的任何类强制执行这个需求第二,Servlet需要ServletConfig对象进行初始化,这是由容器创建的,因为它也有ServletContext对象的引用,它也是由容器创建的。

Servlet是javax.servlet包中定义的接口,HttpServlet是一个类,与Java中的任何其他类一样,它们可以具有构造函数,但是您不能在Java中的接口内部声明构造函数。如果您没有提供显式构造函数,那么编译器将在任何Servlet实现类中添加默认的无参数构造函数。另一个原因是你不应该使用构造函数初始化Servlet,因为Servlet不是由Java代码直接实例化的,而是容器创建实例并将它们保存在池中。由于来自Tomcat和Jetty等Web服务器的容器使用Java Reflection创建Servlet实例,因此必须存在无参数构造函数。因此,如果您提供参数构造函数并忘记编写无参数构造函数,Web容器将无法创建Servlet的实例,因为没有默认构造函数。记住,如果类中存在参数构造函数,Java编译器不会添加默认的无参数构造函数。这就是为什么不建议在Servlet类中提供构造函数。

答案 4 :(得分:0)

在JDK 1.0(最初为其编写servlet)中,动态加载的Java类(例如servlet)的构造函数不能接受参数。因此,为了向新Servlet提供有关其自身及其环境的任何信息,服务器必须调用Servlet的init()方法并传递实现ServletConfig接口的对象。 参见:doc

详细来说,如果要动态加载Java类,则应使用以下方法:

Class<MyClass> clazz = MyClass.class;
Constructor<MyClass> ctor = clazz.getDeclaredConstructor(String.class);
MyClass instance = ctor.newInstance("foo");

但是,自jdk1.1开始编写了返回Class类中的Constructor对象的方法。 在jdk1.0中,您只能使用以下无参数方法:

Object newObject = Class.forName(strFullyQualifiedClassName).newInstance();