Utilizzando CDI + WS / RS + APP a costruire un app
Domanda
@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";
}
}
qui è l'User Manager 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);
}
}
il problema è se non contrassegnare UserService come @Stateless allora il campo Manager è nullo
ma se ho marchio @Stateless, posso avere il campo responsabile iniettato, e funziona l'applicazione come posso ottenere i dati salvati in db
chiedo solo, qual è la ragione di questo?
ed è questo il modo preferito per il cablaggio l'applicazione?
bene, sto pensando di tirare fuori l'EntityManager a un produttore, in modo che possa essere condivisa
Soluzione
il problema è che se io non segnare UserService come @Stateless allora il campo Manager è nullo
Per l'iniezione si verifichi, la classe deve essere un componente gestita ??em>, come i bean enterprise, servlet, Filtri, JSF gestito fagioli, ecc o CDI gestito fagiolo (questo è la parte nuova con Java EE 6, è possibile effettuare qualsiasi classe di un bean gestito con CDI).
Quindi, se non si fanno i tuoi JAX-RS endpoint un EJB, come abilitare l'iniezione? Questo è ben spiegato in JAX-RS e l'integrazione CDI con Glassfish v3 :
Ci sono due modi CDI gestito fagioli sono abilitati:
istanziato da CDI, del ciclo di vita gestito da Jersey. Annotate con
@ManagedBean
e opzionalmente annotate con una portata di annotazione Jersey.un'istanza e gestito da CDI. Annotate con un'annotazione portata CDI, come
@RequestScoped
(senza@ManagedBean
è richiesto)
Suggerisco anche il controllo delle risorse di seguito.
ed è questo il modo preferito per il cablaggio l'applicazione?
direi di sì. CDI è molto bello e ... non vi piace l'iniezione?
bene, sto pensando di tirare fuori l'EntityManager a un produttore, in modo che possa essere condivisa
in comune tra ciò? E perché? Nel caso si, è necessario utilizzare un EntityManager
con una vita che è ambito di una singola transazione ( di transazione con ambito contesto di persistenza ). In altre parole, non condividerlo (e non preoccuparti di apertura e chiusura per ogni richiesta, non si tratta di un'operazione costosa).
Bibliografia
-
2.0 Specification
- JPA
- Sezione 7.6 "Container gestiti Persistence Contesti"
- Sezione 7.6.1 "Container gestiti Transaction-ambito contesto di persistenza"
- Sezione 7.6.2 "Container gestiti estesa contesto di persistenza"
Risorse
Altri suggerimenti
Il @Singleton di annotazione vi aiuterà: http://www.mentby.com/paul-sandoz/jax-rs-on-glassfish-31-ejb-injection.html