El uso de servlet especial automático de inicio para inicializar en el arranque y la aplicación cuota de datos
-
28-09-2019 - |
Pregunta
Necesito conseguir una cierta configuración y conectarse a recursos / objetos / sistemas externos en algún lugar y almacenarla en su alcance de aplicación.
Me puede ver dos maneras de configurar mi aplicación:
- Anulación del
init()
en los servlets existentes y el código no deseado y mantener todos los objetos construidos dentro de esa misma servlet. - Tener algún tipo de servlet inicialización y utilizando su
init()
para hacer el trabajo. A continuación, el almacenamiento de objetos creados enServletContext
compartirlo con mis otros servlets.
¿Qué de lo anterior es mejor enfoque? ¿Hay alguna forma mejor de objetos comparten entre los servlets? Llamando directamente entre sí o así ...?
Solución
Ninguno de los dos es el mejor enfoque. Servlets están destinados para escuchar en eventos HTTP (solicitudes HTTP) y no en los eventos de despliegue (inicio / apagado).
CDI / JSF / EJB disponible? Usar 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.
}
}
Si no estás en Servlet 3.0 y todavía no se puede actualizar, y por lo tanto no se puede utilizar la anotación @WebListener
, entonces es necesario registrarse manualmente en /WEB-INF/web.xml
, como a continuación:
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
para almacenar y obtener los objetos en el ámbito de aplicación (de modo que todos los servlets pueden acceder a ellos), el uso ServletContext#setAttribute()
y #getAttribute()
.
Este es un ejemplo que permite al oyente tienda propia en el ámbito de aplicación:
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("config", this);
// ...
}
y después obtener en un servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Config config = (Config) getServletContext().getAttribute("config");
// ...
}
También está disponible en JSP EL por ${config}
. Por lo que podría hacer que un grano simple también.
CDI disponibles? Uso @Observes
en ApplicationScoped.class
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.
}
}
Este servicio está disponible en un servlet a través @Inject
. Hacerlo si es necesario también @Named
para que esté disponible a través de #{config}
en El también.
anotados deben ser que esto es nuevo, ya CDI 1.1. Si todavía estás en CDI 1.0 y no se puede actualizar, a continuación, elegir otro enfoque.
JSF disponibles? Usar @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.
}
}
Este servicio está disponible a través de #{config}
en El también.
EJB disponibles? Considere @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.
}
}
Este servicio está disponible en un servlet a través @EJB
. Estoy diciendo "considerar", porque no se debe abusar de un EJB por el bien de un gancho de inicio. Por otra parte, un @Singleton
es por defecto de lectura / escritura bloqueado y intented principalmente para la materia de transacciones tales como la programación de tareas en segundo plano.