Usually I'm using @RequestScoped
or @SessionScoped
(from javax.enterprise.context
) to inject objects (for instance in faces beans) using @Inject
.
I am also using EJBs. As I understood, a set of stateless EJB copies (pool) is used to be injected to objects. The reason there are many copies is to ensure one instance of EJB isn't accessed concurrently. When speaking about stateful EJBs (again as I understood), one instance of such is bound to concrete injection point. And they are injected using @EJB
(the stateless ones too).
Frequently I can see on the web examples of using @Stateless
or @Stateful
in conjunction with @Scoped
. What is the meaning of them?
Edit: (trying to clarify as no one responded to this moment):
I'm especially interested whether such scoped annotations change anyhow (and if they - how) moment of creation of EJB's instance.
For my开发者_如何学运维 understanding: if I have, @EJB
annotated field, object of proper class is injected there. If such EJB is stateless, container simply take free instance from the pool of pre-created instances. Pool can be resized if necessary. It is stateless, because object isn't guaranteed to be preserved across method calls of our class (i.e. class which has field containing reference to EJB).
We can also use stateful EJB and in that case one instance is preserved during method calls. As I think, it will be simply injected once per object creation. (There is also singleton EJB, which is shared between all objects).
I can't find the purpose of @Scoped annotations for EJB here.
Edit 2:
One can use such combination of annotations if class is to be injected via EJB and DI (by @Inject
) mechanisms. This is rather, however, special case and not elegant. I am asking if you know any other reasons.
Edit 3: Please see my comment under arjan's answer.
A @Stateless or @Singleton bean may be explicitly scoped to prevent its scope being automatically modified to a scope that may be illegal. E.g. both these bean types are not allowed to be @RequestScoped. See this link for some more info: http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html/CDI.html
@Stateful makes a lot of sense to be (explicitly) scoped. Namely, without a scope you as a programmer have to take care to call the @Remove annotated method. This can be troublesome to guarantee, since such a bean is typically not used in a single method where you can call the @Remove method in a finally block. With a scope, the bean is exactly removed when the scope ends.
Furthermore, without a scope you can't always use injection to obtain a reference to a stateful bean's stub. Namely, every time the injection happens, you'll get a new instance. This is particularly troublesome when injecting a stateful bean in a request scoped (JSF) backing bean, where you have the intent to preserve the stateful bean across a couple of requests.
Then, in combination with @Named, you can also use a session bean directly as a backing bean to flatten your application layers (see e.g. http://jaxenter.com/java-ee-6-overview-35987-2.html). Obviously you want an explicit scope in that case. Now flattening your layers may not be a best practice in larger applications, but for smaller applications and/or people just beginning with Java EE there is definitely a wish to put business logic directly into the backing bean. It's then required that backing beans have access to the same kind of services (mainly transactions) that 'business beans' normally have.
Finally, Gavin King (CDI spec lead) has suggested to always use @Inject instead of @EJB. The only exception concerns remote EJBs, where @EJB is still used.
Part of the confusion around EJB and CDI is that CDI is a new component model in Java EE and still relatively new. Although they integrate fairly well with each other, they are still two different component models and not all best practices have been thought out yet. Reza Rahman (EG member, EJB book writer, and author of CDI implementation CanDI) has suggested that the EJB model could possibly be retrofitted in the future as a set of CDI services. Indeed, in Java EE 7 a step is being made by separating the transactional services from EJB and making them available via (CDI) annotations.
精彩评论