gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 08:45:40 25 4
gpt4 key购买 nike

我需要进行一些配置并在某处连接到外部资源/对象/系统并将其存储在应用程序范围内。

我可以看到两种设置应用程序的方法:

  • 覆盖 init()在现有的 servlet 和所需的代码中,并将所有构造的对象保存在同一个 servlet 中。
  • 拥有某种初始化 servlet 并使用它的 init()做这项工作。然后将创建的对象存储在 ServletContext与我的其他 servlet 共享它。

  • 以上哪种方法更好?有没有更好的方法在 servlet 之间共享对象?直接从彼此之间调用他们……?

    最佳答案

    两者都不是更好的方法。 Servlet 旨在监听 HTTP 事件(HTTP 请求),而不是部署事件(启动/关闭)。

    CDI/EJB 不可用?使用 ServletContextListener

    @WebListener
    public class Config implements ServletContextListener {

    public void contextInitialized(ServletContextEvent event) {
    // Do stuff during webapp's startup.
    }

    public void contextDestroyed(ServletContextEvent event) {
    // Do stuff during webapp's shutdown.
    }

    }
    如果您还没有使用 Servlet 3.0 并且无法升级(因为 Servlet 3.0 是十多年前推出的,这将是时候了),因此无法使用 @WebListener注解,则需要手动注册到 /WEB-INF/web.xml如下所示:
    <listener>
    <listener-class>com.example.Config</listener-class>
    </listener>
    要在应用程序范围内存储和获取对象(以便所有 servlet 都可以访问它们),请使用 ServletContext#setAttribute() #getAttribute() .
    这是一个让监听器将自身存储在应用程序范围内的示例:
        public void contextInitialized(ServletContextEvent event) {
    event.getServletContext().setAttribute("config", this);
    // ...
    }
    然后在 servlet 中获取它:
        protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    Config config = (Config) getServletContext().getAttribute("config");
    // ...
    }
    它也可以通过 ${config} 在 JSP EL 中使用。 .所以你也可以把它变成一个简单的bean。

    CDI 可用吗?使用 @Observes ApplicationScoped.class
    import jakarta.enterprise.context.ApplicationScoped; // And thus NOT e.g. jakarta.faces.bean.ApplicationScoped

    @ApplicationScoped
    public class Config {

    public void init(@Observes @Initialized(ApplicationScoped.class) ServletContext context) {
    // Do stuff during webapp's startup.
    }

    public void destroy(@Observes @Destroyed(ApplicationScoped.class) ServletContext context) {
    // Do stuff during webapp's shutdown.
    }
    }
    这可以通过 @Inject 在 servlet 中使用。 .如有必要,也可以 @Named所以它可以通过 #{config}获得在 EL 中也是如此。
    应该注意的是,这是自 CDI 1.1 以来的新功能。如果您仍在使用 CDI 1.0 并且无法升级,请选择另一种方法。
    如果您对如何在 Tomcat 等非 JEE 服务器上安装 CDI 感到好奇,请访问: How to install and use CDI on Tomcat?

    EJB 可用吗?考虑 @Startup @Singleton
    @Startup
    @Singleton
    public class Config {

    @PostConstruct
    public void init() {
    // Do stuff during webapp's startup.
    }

    @PreDestroy
    public void destroy() {
    // Do stuff during webapp's shutdown.
    }
    }
    这可以通过 @EJB 在 servlet 中使用。 .与其他方法的不同之处在于它默认是事务性的,如果是 @Singleton也读/写锁定。因此,如果您需要将随机 EJB(例如 @Stateless )注入(inject) @WebListener@ApplicationScoped那么您基本上可以将两者合并为一个 @Startup @Singleton .
    也可以看看:
  • How to run a background task in a servlet based web application?
  • ServletContainerInitializer vs ServletContextListener
  • How do I force an application-scoped bean to instantiate at application startup?
  • 关于servlets - 使用特殊的自动启动 servlet 在启动时进行初始化并共享应用程序数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3468150/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com