java - Servlet:init() 方法与内联字段初始化
问题描述
我想问一下以下两种初始化Servlet的实现之间的区别。(内联字段初始化和init
方法)
public class MyServlet extends HttpServlet {
private static String FILE_PATH = "/.../.../.../";
private static String DATE = "date";
private static DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
private static MyDao DAO = new MyDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
...
}
}
VS。
public class MyServlet extends HttpServlet {
private static String FILE_PATH;
private static String DATE;
private static DateTimeFormatter FORMAT;
private static MyDao DAO;
@Override
public void init(){
FILE_PATH = "/.../.../.../";
String DATE = "date";
FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
DAO = new MyDao();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
...
}
}
- Servlet 以任何一种方式初始化时都能正常工作吗?
- 首选哪种初始化方法,原因是什么?
先感谢您!
解决方案
我想问一下以下两种初始化Servlet的实现之间的区别。
不同之处在于执行初始化的时间。
在第一个示例中,它由(例如)另一个引用其中一个static
字段的类或实例化来触发MyServlet
。这种情况只发生一次……在该类的生命周期中。
在第二个示例中,它是由对init()
方法的显式调用触发的。这通常也只会发生一次,但它是在框架的直接控制下发生的。
实际上,对于给定的 servlet 类,在某些情况下init()
可能会被多次调用。该方法实际上是在创建每个MyServlet
实例后调用的。因此,如果您的 Web 配置为两个不同的 servlet 重用同一个MyServlet
类,并且两者都使用同一个类加载器,那么init()
将被调用两次。同样,如果 web 容器可以关闭(即销毁)所有 servlet 并使用与以前相同的类加载器重新创建它们,那么init()
将被第二次调用。(但请注意,由不同类加载器加载的一个类是不同的运行时类,每个类都有自己的一组静态变量。)
Servlet 以任何一种方式初始化时都能正常工作吗?
这取决于:
- 之前是否有其他东西可以访问这些静态变量之一
init()
, - 实例的构造是否
MyDao
依赖于已经初始化/配置的其他东西,以及 init()
多次调用是否有害。
首选哪种初始化方法,原因是什么?
第一个比较简单。越简单越好……如果它满足您的需求。
但是,这不是“二元选择”。您可以以一种方式初始化一些静态,而另一种。例如:
public class MyServlet extends HttpServlet {
private static final String FILE_PATH = "/.../.../.../";
private static final String DATE = "date";
private static final DateTimeFormatter FORMAT =
DateTimeFormatter.ofPattern("yyyyMMdd");
private static MyDao DAO;
@Override
public void init() {
MyServlet.DAO = new MyDao();
}
请注意,(有效)常量的静态变量应尽可能声明final
以防止意外更新。即使他们是private
。
另外,考虑是否DAO
真的应该是一个实例变量。
推荐阅读
- vue.js - 如何在@nuxtjs/auth 中访问授权令牌
- javascript - 为什么我的正则表达式没有得到补充字符类 (^) 中的所有匹配项?
- c# - 带游戏手柄的 Unity Animator 洗涤器
- slack-api - 为团队提供的外部成员的用户 ID 是否唯一
- docker-compose - 在 docker-compose 中使用 ssh 属性对 git 进行身份验证会抛出“.. 不是有效的私钥”
- android - Android:NetworkBoundRsource 与 RemoteMediator
- arrays - 数组未在 C 中合并
- android - Android AlarmManager.setRepeating 未按预期工作
- sqlalchemy - 在 AWS Glue 上安装 cx_Oracle
- reactjs - 从另一个组件更改组件状态