En utilisant CDI + WS / RS + JPA pour construire une application
Question
@Path(value = "/user")
@Stateless
public class UserService {
@Inject
private UserManager manager;
@Path(value = "/create")
@GET
@Produces(value = MediaType.TEXT_PLAIN)
public String doCreate(@QueryParam(value = "name") String name) {
manager.createUser(name);
return "OK";
}
}
ici est le gestionnaire de l'utilisateur impl
public class UserManager {
@PersistenceContext(unitName = "shop")
private EntityManager em;
public void createUser(String name) {
User user = new User();
user.setName(name);
// skip some more initializations
em.persist(user);
}
}
le problème est que si je ne marque pas UserService comme @Stateless alors le champ de gestionnaire est nulle
mais si je marque @Stateless, je peux avoir le champ de gestionnaire injecté, et l'application fonctionne comme je peux obtenir les données enregistrées dans db
se demandant juste, quelle est la raison derrière tout cela?
et est-ce le meilleur moyen pour le câblage de l'application?
Eh bien, je pense à tirer le EntityManager à un producteur, afin qu'il puisse être partagé
La solution
le problème est si je ne marque pas UserService comme @Stateless alors le champ de gestionnaire est nulle
Pour l'injection de se produire, la classe doit être composant géré tels que Enterprise Beans, servlets, filtres, beans gérés JSF, etc ou CDI bean géré (ce est la nouvelle partie avec Java EE 6, vous pouvez faire une classe un bean géré avec CDI).
Donc, si vous ne faites pas votre point final JAX-RS un EJB, comment permettre l'injection? Ceci est bien expliqué dans JAX-RS et l'intégration CDI utilisant Glassfish v3 :
Il y a deux façons CDI géré les haricots sont activés:
instancié par CDI, cycle de vie géré par Jersey. annoter avec
@ManagedBean
et éventuellement annoter avec une annotation portée Jersey.instancié et géré par CDI. Annoter avec une annotation portée de CDI, comme
@RequestScoped
(pas@ManagedBean
est nécessaire)
Je suggère également de vérifier les ressources ci-dessous.
et est-ce le meilleur moyen pour le câblage de l'application?
Je dirais que oui. CDI est très agréable et ... ne vous pas comme l'injection?
bien, je pense à tirer le EntityManager à un producteur, afin qu'il puisse être partagé
Partagé entre quoi? Et pourquoi? En vous cas, vous devez utiliser un EntityManager
avec une durée de vie à une transaction scope unique ( contexte de persistance scope transaction ). En d'autres termes, ne partagent pas (et ne vous inquiétez pas d'ouverture et de fermeture pour chaque demande, ce n'est pas une opération coûteuse).
Références
- JPA 2.0 Spécification
- Section 7.6 "persistance gérée par conteneur Contextes"
- Section 7.6.1 "scope-transaction gérée par conteneur persistance Contexte"
- Section 7.6.2 "gérée par conteneur Contexte persistance étendu"
Ressources
Autres conseils
L'annotation @Singleton contribuera à: http://www.mentby.com/paul-sandoz/jax-rs-on-glassfish-31-ejb-injection.html