3
votes

JAX-RS: Stateless, Singleton, RequestScoped confusion

J'ai vu plusieurs fois plusieurs façons de configurer une ressource JAXRS.

Je veux dire, parfois je vois qu'elles sont annotées comme @Singleton , @Stateless code >, @ApplicationScoped , @RequestScoped , et même sans aucune annotation ou en utilisant les deux.

  • javax.enterprise.context.RequestScoped
  • javax.enterprise.context.ApplicationScoped
  • javax.ejb.Stateless
  • javax.ejb.Singleton
  • javax.inject.Singleton

Quelle annotation dois-je utiliser?

Qu'est-ce que javax.ejb a à voir avec une ressource JAXRS?

Par ailleurs, j'aimerais aussi savoir comment travailler exactement avec l'annotation @Context .

Je veux dire, je ' J'ai vu cela appliqué sur un paramètre, également dans un champ de classe .

@Path("entity")
public class EntityResource {

    @POST
    public Response create(Entity entity, @Context Request request) {
        request...
    }

}

ou,

@Path("entity")
public class EntityResource {

    @Context
    private Request request;

    @POST
    public Response create(Entity entity) {
        this.request...
    }

}

Comment procéder?


0 commentaires

3 Réponses :


1
votes

En ce qui concerne votre première question (portée du bean géré), je dirais qu'aucune annotation de portée ne doit être utilisée car le conteneur java-ee gérera automatiquement la bonne portée pour votre bean selon l'annotation Jax-rs.

Cependant les gars d'ibm semblent avoir une idée différente de la question et déclarent ce qui suit

Bonnes pratiques

Ajoutez des étendues de cycle de vie spécifiques à toute ressource racine et fournisseur JAX-RS classes qui existent dans votre application, dans une archive compatible JCDI. Pour Classes de ressources JAX-RS avec une annotation @ javax.ws.rs.Path, vous pouvez utilisez @ javax.enterprise.context.RequestScoped. Pour Sous-classes javax.ws.rs.core.Application et @ javax.ws.rs.ext.Provider classes annotées, vous devez utiliser @ javax.enterprise.context.ApplicationScoped.

Concernant l'annotation @Context , elle est utilisée pour injecter des objets liés à la requête http actuelle (vous pouvez trouver un liste des instances injectables ici ) et vous pouvez l'utiliser à la fois sur les champs d'instance et les paramètres de méthode


5 commentaires

Peut-il être une ressource JAX-RS ou une ressource EJB?


Jax-rs a son propre conteneur docs .oracle.com / javaee / 7 / api / javax / ws / rs / container /… qui semble être implémenté au-dessus du servlet un stackoverflow.com/questions/41397075/... . Honnêtement, je ne sais pas quel conteneur gère le bean lorsque vous mettez à la fois l'annotation jax-rs et EJB sur votre classe, je soupçonne que l'annotation EJB est simplement ignorée mais cela doit dépendre de l'implémentation de votre serveur


"Le conteneur java-ee gérera automatiquement la bonne portée pour votre bean selon l'annotation Jax-rs" - ce n'est pas vrai. JAX-RS a sa propre notion de portée (voir javax.ws.rs.core.Application.getClasses () vs getSingletons ()), mais une ressource JAX-RS n'est pas un bean CDI par défaut, sauf si vous ajoutez un bean définissant l'annotation, ou travaillez avec bean-discovery-mode = "all".


Comment définir une ressource JAX-RS comme bean CDI? Existe-t-il un bean d'annotations spécifiques à CDI? @Stateless est disponible sur microprofil?


Aucun @Stateless ne fait partie de la spécification EJB qui ne fait pas partie du micro profil, comme indiqué par Herald, vous pouvez utiliser n'importe quelle "annotation de définition de bean" CDI, une portée ( @ApplicationScoped , @SessionScoped , @ConversationScoped , @RequestScoped ) est préférable (sinon le bean utilisera le @Dependent pseudo portée)



6
votes

Il n'est pas nécessaire d'utiliser des annotations EJB ou CDI dans une classe de ressources JAX-RS - à moins que vous ne souhaitiez utiliser les fonctionnalités EJB ou CDI dans la même classe.

Si vous voulez injecter un bean CDI dans les classes de ressources, la classe de ressources doit être un bean CDI lui-même, vous devez donc ajouter une annotation de portée, de préférence @ javax.enterprise.context.RequestScoped .

Si vous utilisez une annotation EJB comme @Stateless , l'injection fonctionnera également, puisque les EJB sont également des beans CDI (mais pas l'inverse). Cependant, un beans sans état a un cycle de vie différent, et il est transactionnel par défaut.

Par contre, si vous avez besoin de transactions, vous pouvez également utiliser @ javax.transaction.Transctional en combinaison avec @RequestScoped et @Path .

Contexte:

Les EJB sont un peu obsolètes dans la plupart des cas. Ils sont venus en premier, avant JAX-RS et CDI, mais ces jours-ci, CDI est considéré comme le mécanisme unificateur d'injection de dépendances dans Java EE / Jakarta EE, et les spécifications plus anciennes sont en cours de mise à jour pour être plus étroitement intégrées à CDI.


2 commentaires

pourquoi "de préférence RequestScoped"?


Parce que chaque appel de méthode de ressource JAX-RS correspond à une requête HTTP. Si vous utilisez une portée plus longue, votre classe doit être thread-safe.



0
votes

L'utilisation de @Stateless sur une ressource JAX-RS peut être utile pour empêcher le serveur Web de créer une nouvelle ressource pour chaque appel (comme c'est le cas en utilisant le @RequestScoped annotation). Lors de l'utilisation de l'annotation @Stateless , le serveur créera un pool de ressources qui peut être configurable. Vous bénéficierez également des avantages des transactions.


2 commentaires

Qu'en est-il de ApplicationScoped alors. Je veux dire, quelle est la différence entre @ApplicationScoped et @Stateless alors?


@Jordi: En utilisant un pool (c'est-à-dire en utilisant @Stateless ), vous pouvez contrôler le trafic sur votre application (car un seul appel http sera attaché à une seule ressource sans état). Cependant, avec le bean à portée d'application, vous ne pouvez pas contrôler le trafic des requêtes entrantes. Aucun n'est meilleur que l'autre, cela dépend juste de ce que vous voulez faire.