Java 我们可以将init方法的用途替换为servlet构造函数吗?
我们可以将init方法的pupose替换为servlet构造函数吗?Java 我们可以将init方法的用途替换为servlet构造函数吗?,java,servlets,Java,Servlets,我们可以将init方法的pupose替换为servlet构造函数吗? 我的问题是,为什么servlet需要一个单独的方法int(ServletConfig)用于初始化,我们可以通过使用参数化构造函数letXServlet(ServletConfig)来实现同样的效果和容器可以调用相同的参数。可能是因为无法在接口中为构造函数指定参数签名。可能是因为无法在接口中为构造函数指定参数签名。通常认为在构造函数中执行逻辑是一种不好的做法(它应该只初始化字段并在一致状态下创建对象)。这也使得测试更加困难 此外
我的问题是,为什么servlet需要一个单独的方法
int(ServletConfig)
用于初始化,我们可以通过使用参数化构造函数letXServlet(ServletConfig)来实现同样的效果
和容器可以调用相同的参数。可能是因为无法在接口中为构造函数指定参数签名。可能是因为无法在接口中为构造函数指定参数签名。通常认为在构造函数中执行逻辑是一种不好的做法(它应该只初始化字段并在一致状态下创建对象)。这也使得测试更加困难
此外,执行注入要困难得多——当使用init
时,容器可以创建一个servlet,注入依赖项并运行init
。使用构造函数,您希望所有依赖项都已设置。Wicket通过将Spring Bean从超类构造函数注入page类来解决这个问题——因为超类构造函数首先运行。但是从超类构造函数修改子类字段似乎是错误的
也就是说,使用单独的
init
方法会使一些事情变得更简单、更易于维护。还要注意,EJB也会促进@PostConstruct
注释。通常认为在构造函数中执行逻辑是一种不好的做法(它应该只初始化字段并在一致状态下创建对象).这也使得测试更加困难
此外,执行注入要困难得多——当使用init
时,容器可以创建一个servlet,注入依赖项并运行init
。使用构造函数,您希望所有依赖项都已设置。Wicket通过将Spring Bean从超类构造函数注入page类来解决这个问题——因为超类构造函数首先运行。但是从超类构造函数修改子类字段似乎是错误的
也就是说,使用单独的
init
方法会使一些事情变得更简单、更易于维护。还要注意,EJB也促进了@PostConstruct
注释。我猜这个选择是为了简化servlet的编码。在当前情况下,不需要特定初始化的servlet可以像是:
public class MyServlet extends HttpServlet {
// doGet, doPost, etc.
}
public class MyServlet extends HttpServlet {
public MyServlet(ServletConfig config) {
super(config);
}
// doGet, doPost, etc.
}
如果servlet是使用构造函数初始化的,则需要按照以下方式进行编码:
public class MyServlet extends HttpServlet {
// doGet, doPost, etc.
}
public class MyServlet extends HttpServlet {
public MyServlet(ServletConfig config) {
super(config);
}
// doGet, doPost, etc.
}
顺便说一句,他们甚至引入了一个no-arg init方法,可以用来避免被迫调用
super.init(config)
我想这个选择是为了简化servlet的编码。在当前情况下,不需要特定初始化的servlet可以这样编码:
public class MyServlet extends HttpServlet {
// doGet, doPost, etc.
}
public class MyServlet extends HttpServlet {
public MyServlet(ServletConfig config) {
super(config);
}
// doGet, doPost, etc.
}
如果servlet是使用构造函数初始化的,则需要按照以下方式进行编码:
public class MyServlet extends HttpServlet {
// doGet, doPost, etc.
}
public class MyServlet extends HttpServlet {
public MyServlet(ServletConfig config) {
super(config);
}
// doGet, doPost, etc.
}
顺便说一句,他们甚至引入了一个no-arg init方法,可以用来避免被强制调用super。init(config)
int(ServletConfig)是Servlet的生命周期方法。Servlet容器正在调用它
我们可以替换超类servlet的参数构造函数中的init方法代码。
但是我们不能强迫开发人员调用超级类构造函数
比如说
/*If generic servlet has a constructor like this*/
public GenericServlet(ServletConfig config){
....
}
/*And Developers servlet is calling only default servlet.*/
public MyServlet(){
super();
}
所以在这个场景中,servlet永远不会初始化。这会导致问题。因为ServletConfig obj没有初始化。
我们不能强迫用户调用特定的超类构造函数。int(ServletConfig-config)是Servlet的生命周期方法,它被Servlet容器调用
我们可以替换超类servlet的参数构造函数中的init方法代码。
但是我们不能强迫开发人员调用超级类构造函数
比如说
/*If generic servlet has a constructor like this*/
public GenericServlet(ServletConfig config){
....
}
/*And Developers servlet is calling only default servlet.*/
public MyServlet(){
super();
}
所以在这个场景中,servlet永远不会初始化。这会导致问题。因为ServletConfig obj没有初始化。
我们不能强迫用户调用特定的超类构造函数。简短回答:否
长答覆:
如果servlet包含构造函数和init方法,您将看到首先调用构造函数,然后调用init方法(使用sysout语句进行尝试)
servlet是一个java类,因此它必须遵循java过程,因此首先调用构造函数,然后调用init方法(注意,像tomcat这样的servlet容器调用init方法,因为这就是servlet的初始化方式;请阅读servlet规范)
因此,如果您需要执行一些特定于您的业务需要的操作(例如创建一个DB连接或读取一组用户详细信息等),那么构造函数并不是放置这些内容的最佳位置
通常构造函数不应该有任何复杂的逻辑/业务处理。他们应该初始化最小的成员变量,并将复杂的事情留待以后处理;对于servlet,可以通过init方法完成繁重的工作
还要注意,在调用init()时,servlet容器已经启动并准备好了它的系统资源,即它已经初始化了JNDi名称绑定、数据源等等。
因此,在某种程度上,它保证了当您调用init()时,它将为您准备好系统资源
servlet 3规范说明如下:
2.3.1 servlet容器负责加载和实例化
用于加载和实例化servlet。加载和实例化
可能在容器启动时发生,或延迟到
容器确定服务请求所需的servlet
servlet引擎启动后,必须找到所需的servlet类
servlet容器加载servlet
使用普通Java类加载工具初始化。加载可能是
从本地文件系统、远程文件系统或其他网络
服务。