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

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

我需要获得一些配置,并连接到某个地方的外部资源/对象/系统,并将其存储在应用程序范围内。

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

  • 覆盖

    init()

    在现有的servlet和必需的代码中,并将所有构造的对象保存在同一个servlet中。
  • 具有某种初始化servlet,并使用其

    init()

    去做这项工作。然后将创建的对象存储在

    ServletContext

    与我的其他servlet共享它。

以上哪种方法更好?是否有更好的方法在servlet之间共享对象?直接给他们打电话吗.?


繁星淼淼
浏览 442回答 1
1回答

一只斗牛犬

两者都不是更好的方法。servlet的目的是侦听HTTP事件(HTTP请求),而不是侦听部署事件(启动/关闭)。CDI/JSF/EJB不可用?使用ServletContextListener@WebListenerpublic&nbsp;class&nbsp;Config&nbsp;implements&nbsp;ServletContextListener&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;contextInitialized(ServletContextEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Do&nbsp;stuff&nbsp;during&nbsp;webapp's&nbsp;startup. &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;contextDestroyed(ServletContextEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Do&nbsp;stuff&nbsp;during&nbsp;webapp's&nbsp;shutdown. &nbsp;&nbsp;&nbsp;&nbsp;}}如果您还没有使用Servlet3.0并且无法升级,那么就不能使用@WebListener注释,则需要手动在/WEB-INF/web.xml如下所示:<listener> &nbsp;&nbsp;&nbsp;&nbsp;<listener-class>com.example.Config</listener-class></listener>要在应用程序作用域中存储和获取对象(以便所有servlet都可以访问它们),请使用ServletContext#setAttribute()和#getAttribute().下面是一个让侦听器将自己存储在应用程序范围中的示例:&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;contextInitialized(ServletContextEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.getServletContext().setAttribute("config",&nbsp;this); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;}然后在servlet中获得它:&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;doGet(HttpServletRequest&nbsp;request,&nbsp;HttpServletResponse&nbsp;response)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config&nbsp;config&nbsp;=&nbsp;(Config)&nbsp;getServletContext().getAttribute("config"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;}它也可以在JSPEL中使用${config}..所以你也可以做一个简单的豆子。有CDI吗?使用@Observes在……上面ApplicationScoped.classimport&nbsp;javax.enterprise.context.ApplicationScoped;@ApplicationScopedpublic&nbsp;class&nbsp;Config&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;init(@Observes&nbsp;@Initialized(ApplicationScoped.class)&nbsp;ServletContext&nbsp;context)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Do&nbsp;stuff&nbsp;during&nbsp;webapp's&nbsp;startup. &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;destroy(@Observes&nbsp;@Destroyed(ApplicationScoped.class)&nbsp;ServletContext&nbsp;context)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Do&nbsp;stuff&nbsp;during&nbsp;webapp's&nbsp;shutdown. &nbsp;&nbsp;&nbsp;&nbsp;}}这在servlet中是可用的@Inject..必要的话也要做@Named所以它可以通过#{config}在艾尔也是。应该指出,这是自CDI 1.1以来的新情况。如果您仍然使用CDI1.0并且无法升级,那么请选择另一种方法。JSF可用吗?使用@ManagedBean(eager=true)import&nbsp;javax.faces.bean.ManagedBeanimport&nbsp;javax.faces.bean.ApplicationScoped;@ManagedBean(eager=true)@ApplicationScopedpublic&nbsp;class&nbsp;Config&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;@PostConstruct &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;init()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Do&nbsp;stuff&nbsp;during&nbsp;webapp's&nbsp;startup. &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;@PreDestroy &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;destroy()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Do&nbsp;stuff&nbsp;during&nbsp;webapp's&nbsp;shutdown. &nbsp;&nbsp;&nbsp;&nbsp;}}这是通过#{config}在艾尔也是。EJB可用吗?考虑@Startup@Singleton@Startup@Singletonpublic&nbsp;class&nbsp;Config&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;@PostConstruct &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;init()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Do&nbsp;stuff&nbsp;during&nbsp;webapp's&nbsp;startup. &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;@PreDestroy &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;destroy()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Do&nbsp;stuff&nbsp;during&nbsp;webapp's&nbsp;shutdown. &nbsp;&nbsp;&nbsp;&nbsp;}}这在servlet中是可用的@EJB..我说的是“考虑”,因为您不应该为了启动钩子而滥用EJB。此外,@Singleton默认情况下,读/写是锁定的,主要用于事务处理,例如调度后台作业。另见:如何在基于servlet的Web应用程序中运行后台任务?ServletContainerInitiizer vs ServletContextListener如何在应用程序启动时强制应用程序范围内的bean实例化?
打开App,查看更多内容
随时随地看视频慕课网APP