以我对Servlet的理解,Servlet将由Container实例化,其
init()
方法将被调用一次,Servlet将像单例一样生存,直到JVM关闭。
我不希望我的 servlet 被序列化,因为当应用程序服务器恢复或正常启动时它将被构造新的。 servlet 不应包含特定于会话的成员,因此将其写入磁盘并重新实例化是没有意义的。 这个有实际用途吗?
我担心的是,我在其中放置了一些不可序列化的字段,然后我的应用程序将在生产环境中神秘地失败,在生产环境中将发生不同类型的会话复制。
从技术上讲,我相信 servlet 容器可以将 servlet 对象“钝化”到磁盘,这与 EJB 会话 bean 的方式类似。因此,如果您的应用程序因不可序列化字段而失败,那么您提出的问题是正确的。
在实践中,我从未听说过容器可以做到这一点,所以它实际上只是早期 J2EE 糟糕的旧时代的遗留包袱。我不会担心。
HttpServlet
可以序列化到磁盘并在 servlet 容器重新启动后继续存在。例如,Tomcat 允许您设置一个标志来实现这种生存。下一个选项是使用 JNDI 进行传输。这不是垃圾,它只在极端用例中使用。
谷歌似乎表明这样做是为了让容器作者可以有选择,如果他们愿意的话。
您认为 servlet 不应包含特定于会话的成员是正确的,事实上,我认为您希望状态尽可能少。如果您将所有内容存储在 Session 或 ServletConfig 中,我认为您能够在序列化中幸存下来。
就像 Session 对象被序列化以在那些提供集群选项的 servlet 容器的缓存中生存一样,容器也可能有一个选项可以将 Servlet 实例传输到另一个集群节点?我只是在这里猜测
Serialized 用作分布式环境中会话属性的标记接口。
SRV.7.7.2 分布式环境 (JSR-154)
在标记为 distributable 的应用程序中,所有请求 是会话的一部分,必须由一个 Java 虚拟机处理 (“JVM”)一次。容器必须能够处理所有对象 使用 setAttribute 放置到 HttpSession 类的实例中 或适当的 putValue 方法。以下限制是 为满足这些条件而强加:
- 容器必须接受实现 Serialized 接口的对象。
- 会话的迁移将由容器特定的设施来处理。
分布式 servlet 容器必须抛出一个 对于 容器无法处理的对象,存在 IllegalArgumentException 支持会话存储迁移所需的机制 他们。
分布式servlet容器必须支持必要的机制 为了 迁移实现 Serialized 的对象。
(...)
容器提供商可以确保可扩展性和服务质量 具有负载平衡和故障转移等功能 从任何活动节点移动会话对象及其内容 分布式系统到系统的不同节点。 如果分布式 容器坚持或迁移会话以提供质量 服务功能,它们不限于使用本机 JVM 用于序列化 HttpSession 及其的序列化机制 属性。开发人员不能保证容器会调用 会话属性上的 readObject 和 writeObject 方法(如果它们) 实现它们,但保证 Serialized 闭包 他们的属性将被保留。