Utilizzando speciale servlet avvio automatico per inizializzare all'avvio e l'applicazione condivisione dei dati
-
28-09-2019 - |
Domanda
Ho bisogno di avere un po 'di configurazione e connettersi a risorse / oggetti / sistemi esterni da qualche parte e conservarlo in ambito di applicazione.
posso vedere due modi di impostare la mia domanda:
- Override del
init()
nelle servlet esistenti e il codice non necessario e mantenendo tutti gli oggetti costruiti all'interno di quella stessa servlet. - Avere una specie di servlet inizializzazione e utilizzando il suo
init()
per fare il lavoro. Poi la memorizzazione di oggetti creati inServletContext
di condividerlo con i miei altri servlet.
Quale di sopra è l'approccio migliore? C'è un modo migliore per gli oggetti di condivisione tra le servlet? chiamandoli direttamente da un altro o in modo ...?
Soluzione
Nessuno dei due è l'approccio migliore. Servlet sono destinati per l'ascolto su HTTP eventi (le richieste HTTP), non sugli eventi di implementazione (avvio / arresto).
CDI / JSF / EJB non è disponibile? Utilizzare 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.
}
}
Se non sei su Servlet 3.0 e ancora non è possibile aggiornare, e quindi non può utilizzare @WebListener
annotazione, allora avete bisogno di registrare manualmente in /WEB-INF/web.xml
come di seguito:
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
Per memorizzare e ottenere oggetti nel campo di applicazione (in modo che tutti i servlet possono accedervi), uso ServletContext#setAttribute()
e #getAttribute()
.
Ecco un esempio che lascia il negozio ascoltatore stesso nella portata di applicazione:
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("config", this);
// ...
}
e quindi ottenere in un servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Config config = (Config) getServletContext().getAttribute("config");
// ...
}
E 'disponibile in JSP EL anche da ${config}
. Così si potrebbe rendere un fagiolo semplice così.
CDI disponibili? Usa @Observes
su 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.
}
}
Questo è disponibile in un servlet via @Inject
. Rendono se necessario, anche @Named
modo che sia disponibile tramite #{config}
in EL pure.
Notato dovrebbe essere che questa è una novità in quanto CDI 1.1. Se siete ancora su CDI 1.0 e non è possibile aggiornare, quindi scegliere un altro approccio.
JSF disponibili? Utilizzare @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.
}
}
Questo è disponibile tramite #{config}
in EL pure.
EJB disponibili? Considerare @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.
}
}
Questo è disponibile in un servlet via @EJB
. Sto dicendo "prendere in considerazione", perché non si dovrebbe abusare di un EJB per il bene di un gancio di avvio. Inoltre, una @Singleton
è per default di lettura / scrittura bloccato e in primo luogo destinata ad essere roba transazionale, come i lavori di programmazione di fondo.