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

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

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

>覆盖现有servlet中的init()和所需的代码,并将所有构造的对象保留在同一个servlet中。
>使用某种初始化servlet并使用其init()来完成工作。然后在ServletContext中存储创建的对象,以便与我的其他servlet共享。

以上哪个更好的方法?有没有更好的方式在servlet之间共享对象?直接打电话给他们…?

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

CDI / JSF / 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可以访问它们),请使用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。

如果您尚未使用Servlet 3.0,无法升级,因此无法使用@WebListener注释,那么您需要在/WEB-INF/web.xml中手动注册,如下所示:

<listener>
    <listener-class>com.example.Config</listener-class>
</listener>

CDI可用?在ApplicationScoped.class上使用@Observes

import javax.enterprise.context.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,所以它也可以通过EL中的#{config}使用。

应该是CDI 1.1这是新的。如果您仍然在CDI 1.0上,无法升级,请选择另一种方法。

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

import javax.faces.bean.ManagedBean
import javax.faces.bean.ApplicationScoped;

@ManagedBean(eager=true)
@ApplicationScoped
public class Config {

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

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

这也可以通过EL中的#{config}来实现。

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中使用。我在说“考虑”,因为您不应该为了启动挂钩而滥用EJB。此外,@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?

http://stackoverflow.com/questions/3468150/using-special-auto-start-servlet-to-initialize-on-startup-and-share-application

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:servlets – 使用特殊的自动启动servlet在启动时初始化并共享应用程序数据