【问题标题】:Having service layer objects in servlet's fields在 servlet 的字段中包含服务层对象
【发布时间】:2017-02-23 06:04:07
【问题描述】:
我目前正在使用 Hibernate 编写 J2EE 应用程序并在 Tomcat 上运行它。该项目分为几个部分(DAO、服务、控制器(servlet)、视图(JSP))。 DAO 和服务是单例的。为了解耦控制器和服务,我将服务接口的引用存储为 servlet 的字段。 Sonarqube 告诉这些字段必须标记为瞬态,或者服务类必须实现 Serializable,或者应该删除这些字段。那么,在 servlet 中有字段是不是很糟糕?如果我只是将它们标记为瞬态呢?
【问题讨论】:
标签:
java
servlets
jakarta-ee
serializable
transient
【解决方案1】:
只要生成的对象图是不可变的或无状态的,将对象引用存储在 servlet 的实例字段中是完全安全的。如果不是这种情况,那么您将遇到并发问题。
从技术上讲,这些字段需要对它们应用 transient 修饰符,因为某些容器会在受控关闭期间(或任何其他方便的时间)使用序列化保存 servlet 的状态。这样做的结果是您的 servlet 需要实现 private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException 方法来恢复您的服务引用字段。
阅读java.io.Serializable javadocs 了解更多信息。
【解决方案2】:
在 Servlet 中声明和使用变量不是一个好习惯,因为同一个实例在不同线程之间共享。
在某些情况下,Servlet 状态可能会持续存在,具体取决于 Web 容器。警告是因为在这种情况下容器可能会抛出错误。