2009-03-06 6 views
11

Nous savons tous que dans la couche Web, il est possible qu'une seule instance d'une servlet donnée existe et qu'elle traite plusieurs requêtes. Cela peut entraîner des problèmes de thread dans les variables d'instance.Est-il possible d'injecter un EJB dans une servlet en tant que variable d'instance?

Ma question est, est-il sécuritaire d'injecter un EJB en utilisant l'annotation @EJB dans une servlet comme une variable d'instance?

Mon instinct initial serait non, en supposant que la même instance de l'EJB traiterait plusieurs demandes en même temps. Il semblerait que ce serait aussi l'instinct d'un certain nombre d'autres programmeurs: Don't inject to servlets

Cependant, ai-je sauté à la mauvaise conclusion. De toute évidence, ce qui est injecté dans le servlet est un proxy, sous le capot, le conteneur traite-t-il réellement chaque requête avec une instance différente et maintient la sécurité du thread? Comme ce forum le suggère: Do inject to servlets

Il semble y avoir beaucoup d'opinions contradictoires. QUI EST CORRECT???

Répondre

3

Votre référence "Ne pas injecter aux servlets" ne mentionne rien sur les annotations ejbs ou @ejb. Il parle d'objets non thread-safe tels que PersistenceContext.

Par EJB spec, vous pouvez accéder aux ejbs à partir de divers clients distants, y compris les servlets (spécification EJB 3.0 (JSR-220) - Section 3.1). L'injection d'ejb à l'aide de l'annotation @EJB est une méthode d'obtention d'une interface EJB via l'injection de dépendance (section 3.4.1) qui est une alternative à la recherche d'objets ejb dans l'espace de noms JNDI. Il n'y a donc rien de spécial à propos de l'annotation @EJB en ce qui concerne les EJB obtenus. Donc, sur la base des spécifications EJB 3.0, il est courant d'obtenir des ejbs à partir des servlets en utilisant l'annotation @EJB.

+0

Cette réponse est correcte dans la mesure où elle va, mais elle ne répond pas aux préoccupations de sécurité de l'OP. Je crois que la réponse de inferreddesign ci-dessous devrait être la bonne. –

+0

Je suppose qu'un EJB injecté avec @Inject (CDI, JEE 6) sera tout aussi sûr, n'est-ce pas? – marcus

0

Je pense que la réponse simple est que vous n'êtes pas garanti que c'est sûr.

La raison en est qu'il n'y a rien d'explicite dans la spécification EJB qui stipule que les interfaces home EJB doivent être thread-safe. La spécification décrit le comportement de la partie côté serveur uniquement. Ce que vous trouverez probablement, c'est que les squelettes des clients sont réellement thread-safe, mais vous auriez besoin de regarder comment ils sont implémentés par la bibliothèque que vous utilisez. La partie d'annotation va simplement s'étendre dans un localisateur de service afin que vous n'achetiez rien.

11

Il est sûr d'injecter un EJB dans une servlet en tant que variable d'instance de servlet, tant que l'EJB est sans état. Vous NE devez JAMAIS injecter un Bean Stateful dans une servlet.

Vous devez implémenter votre EJB sans état car il ne contient aucune variable d'instance qui elle-même contient une valeur avec état (comme Persistence Context). Si vous avez besoin d'utiliser le contexte de persistance, vous devez en obtenir une instance dans les méthodes de l'EJB. Vous pouvez le faire en ayant une PersistenceContextFactory en tant que variable d'instance EJB, puis vous obtenez une instance du gestionnaire d'entités de Factory dans la méthode de l'EJB. PersistanceContextFactory est thread-safe, il peut donc être injecté dans une variable d'instance.

Tant que vous respectez les règles mentionnées ci-dessus, il devrait être thread-safe pour injecter un Stateless Bean dans un Servlet

1

Il est un sac mélangé.

Les fèves de session sans état peuvent être injectées et sont sûres.En effet, même si une seule instance d'un stub est utilisée, l'accès aux méthodes sera sérialisé par le conteneur.

Je pense que ce que dit inferreddesign est pas vrai. Peu importe si le bean de session sans état utilise un contexte de persistance. Un seul appelant accédera jamais à une seule instance de bean en même temps, donc même si le contexte de persistance n'est pas thread-safe, l'EJB protège contre l'accès multiple. Pensez-y comme si chaque méthode de bean de session a le mot-clé synchronisé appliqué à elle.

Le principal problème avec l'injection d'un EJB dans une servlet, je pense est la performance. L'instance de stub unique deviendra une zone majeure de conflit lorsque plusieurs demandes sont mises en file d'attente en attendant qu'une méthode de bean de session soit exécutée pour elles.

+0

Le talon sera synchronisé, mais je pense qu'il sera rapidement envoyé à l'un des EJB regroupés pour faire le vrai travail. A moins que le talon ne détienne le verrou pendant tout l'appel, ce qui serait un très mauvais choix d'implémentation ... – marcus

Questions connexes