L'utilisation servlet spéciale de démarrage automatique pour initialiser des données de démarrage et l'application d'actions

StackOverflow https://stackoverflow.com/questions/3468150

Question

Je dois obtenir une configuration et se connecter à des ressources externes / objets / systèmes quelque part et le stocker dans champ d'application.

Je vois deux façons de configurer mon application:

  • Outrepasser la init() dans les servlets existants et le code nécessaire et il garder tous les objets construits à l'intérieur même servlet.
  • Avoir une sorte d'un servlet d'initialisation et en utilisant son init() pour faire le travail. Ensuite, le stockage d'objets créés dans ServletContext pour la partager avec mes autres servlets.

Ce qui précède est de meilleure approche? Y at-il une meilleure façon de partager des objets entre servlets? les appeler directement les uns des autres ou si ...?

Était-ce utile?

La solution

Aucun des deux est la meilleure approche. Servlets sont destinés à écouter les événements HTTP (requêtes HTTP), et non pas sur les événements de déploiement (démarrage / arrêt).


CDI / JSF / EJB indisponible? Utilisez 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 vous n'êtes pas sur Servlet 3.0 encore et ne peut pas mettre à niveau et ne peut donc pas utiliser l'annotation @WebListener, alors vous devez vous inscrire manuellement dans /WEB-INF/web.xml comme ci-dessous:

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

Pour stocker et obtenir des objets dans le champ d'application (de sorte que tous les servlets peuvent y accéder), utilisez ServletContext#setAttribute() et #getAttribute() .

Voici un exemple qui permet au magasin d'auditeur lui-même dans le champ d'application:

    public void contextInitialized(ServletContextEvent event) {
        event.getServletContext().setAttribute("config", this);
        // ...
    }

et puis l'obtenir dans un servlet:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        Config config = (Config) getServletContext().getAttribute("config");
        // ...
    }

Il est également disponible dans JSP EL par ${config}. Ainsi, vous pouvez faire un haricot simple ainsi.


CDI disponibles? Utilisez @Observes sur 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.
    }
}

Il est disponible dans un servlet via @Inject. Faire si nécessaire aussi @Named il est disponible via #{config} dans EL ainsi.

A pris note devrait être que ce nouveau depuis CDI 1.1. Si vous êtes toujours sur CDI 1.0 et ne peut pas mettre à niveau, puis choisir une autre approche.


JSF disponible? Utilisez @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.
    }
}

Il est disponible via #{config} dans EL ainsi.


EJB disponible? @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.
    }
}

Il est disponible dans un servlet via @EJB. Je dis « considérer », parce que vous ne devriez pas abuser d'un EJB pour le bien d'un crochet de démarrage. De plus, un @Singleton est par défaut de lecture / écriture verrouillé et principalement pour des trucs intented transactionnels tels que les travaux d'arrière-plan de programmation.

Voir aussi:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top