java - Servlet 继承以及全局对象创建和访问

标签 java servlets inheritance global-variables

我必须首先为这个问题建立框架。我正在创建一个动态 Servlet 环境,该环境使用全局可访问、 volatile 、线程安全的内存中数据缓存,为环境中的每个 Servlet 存储并提供对其自身的访问。

类似这样的事情:

public class CoreServlet extends HttpServlet {

    protected globalCache;

    public void init(ServletConfig config){
        globalCache = new InMemoryCache();
    }

    doGet...
    doPost...
 }

然后,许多其他 servlet 会扩展该 servlet,这些 servlet 在 globalCache 上执行辅助任务(更改值等)。

 public class subServletA extends CoreServlet {

      doGet...
      doPost...
 }

 public class subServletB extends CoreServlet {

      doGet...
      doPost...
 }

等等...

通过实验,我发现这样做会导致每次扩展 CoreServlet 时重新执行整个 CoreServlet 代码(包括所有全局变量实例化和 init 方法),最终实例化了 6 个 globalCache 副本(这是一个严重内存密集型对象)。

我通过在第一次运行 init 方法后触发的 ServletContext 中分配一个标志来修复此部分,这样它将跳过所有其他实例化,只留下一个 globalCache,但我遇到了 Java 似乎任意更改缓存值的问题。

那么,技术问题是:为什么 Java 会重复整个父 servlet 代码?

更多设计方面的问题:是否有更好的方法来实现亚毫秒级延迟、全局(在我的应用程序内)可访问的缓存?

我曾考虑过使用类似 memcached 的解决方案,但出于性能目的,我仍然希望将缓存保留在 RAM 中。

欢迎任何想法、创意或最佳实践建议。

最佳答案

下面的代码应该可以解决这个问题,因为它将把您的全局缓存对象放入 Web 应用程序的 ServletContext 中,从而与所有 servlet 共享它。

public class CoreServlet extends HttpServlet {
  protected globalCache;

  @Override
  public void init(ServletConfig config){
    synchronized(CoreServlet.class) {
      globalCache = (InMemoryCache) config.getServletContext().getAttribute("core.cache");

      if (globalCache == null) {
        globalCache = new InMemoryCache();
        config.getServletContext().setAttribute("core.cache", globalCache);
      }
    }
  }
}

如果扩展CoreServlet,Servlet 容器将调用init() 方法。这就是为什么您最终会得到多个缓存对象实例的原因。

关于java - Servlet 继承以及全局对象创建和访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26347467/

相关文章:

servlets - 使用特殊的自动启动 servlet 在启动时进行初始化并共享应用程序数据

tomcat - 处理 Url 中不区分大小写的应用程序名称

java - 构造函数 Bicycle 类不能应用于给定类型;必需 : int, 找到 int:无参数原因:实际参数和前一个参数长度不同

c++ - 我应该初始化抽象类的成员吗?

java - Java toString 中的 NullPointerException

java - JBoss 将 ROOT.WAR 重命名为默认值

java - 为什么 java.lang.Thread 在 Google App Engine 白名单中?

c++ - 关于多重继承和虚继承

java - 每个异步线程都运行一个无限循环

java - 汤姆EE : JMS Provider - ActiveMQ with AMQP Wire protocol