两者都不是更好的方法。 Servlet 旨在侦听 HTTP 事件(HTTP 请求),而不是部署事件(启动/关闭)。
@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。
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,这样它也可以通过 EL 中的#{config} 获得。
值得注意的是,这是自 CDI 1.1 以来的新功能。如果您仍在使用 CDI 1.0 并且无法升级,请选择其他方法。
如果您对如何在 Tomcat 等非 JEE 服务器上安装 CDI 感到好奇,请访问:How to install and use CDI on Tomcat?
@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)注入到 @WebListener 或 @ApplicationScoped 中,那么您基本上可以将两者合并到一个 @Startup @Singleton 中。
另见: