为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

繁星淼淼 2019-06-04 16:23:34
使用特殊的自动启动servlet在启动时初始化并共享应用程序数据我需要获得一些配置,并连接到某个地方的外部资源/对象/系统,并将其存储在应用程序范围内。我可以看到设置应用程序的两种方法:覆盖init()在现有的servlet和必需的代码中,并将所有构造的对象保存在同一个servlet中。具有某种初始化servlet,并使用其init()去做这项工作。然后将创建的对象存储在ServletContext与我的其他servlet共享它。以上哪种方法更好?是否有更好的方法在servlet之间共享对象?直接给他们打电话吗.?
查看完整描述

1 回答

?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

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


CDI/JSF/EJB不可用?使用ServletContextListener

@WebListenerpublic 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.
    }}

如果您还没有使用Servlet3.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");
        // ...
    }

它也可以在JSPEL中使用${config}..所以你也可以做一个简单的豆子。


有CDI吗?使用@Observes在……上面ApplicationScoped.class

import javax.enterprise.context.ApplicationScoped;@ApplicationScopedpublic 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.
    }}

这在servlet中是可用的@Inject..必要的话也要做@Named所以它可以通过#{config}在艾尔也是。

应该指出,这是自CDI 1.1以来的新情况。如果您仍然使用CDI1.0并且无法升级,那么请选择另一种方法。


JSF可用吗?使用@ManagedBean(eager=true)

import javax.faces.bean.ManagedBeanimport javax.faces.bean.ApplicationScoped;@ManagedBean(eager=true)@ApplicationScopedpublic class Config {

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

    @PreDestroy
    public void destroy() {
        // Do stuff during webapp's shutdown.
    }}

这是通过#{config}在艾尔也是。


EJB可用吗?考虑@Startup@Singleton

@Startup@Singletonpublic class Config {

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

    @PreDestroy
    public void destroy() {
        // Do stuff during webapp's shutdown.
    }}

这在servlet中是可用的@EJB..我说的是“考虑”,因为您不应该为了启动钩子而滥用EJB。此外,@Singleton默认情况下,读/写是锁定的,主要用于事务处理,例如调度后台作业。

另见:


查看完整回答
反对 回复 2019-06-04
  • 1 回答
  • 0 关注
  • 407 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信