I would like to know, what are the principal differences between :
I know that a @SessionScoped and a @Stateful allows to create a new instance for each client. I also know that for the @ApplicationScoped and @Singleton / @Stateless they are shared between the clients.
=> But when should I consider it's better to choose an EJB, or the other?
@SessionScoped
denotes a scope while @Stateful
is in a way what we would now call a stereotype. @Stateful
adds a number a services to a bean, among which transactional behavior and passivation.
Central to @Stateful
is however its session behavior, which indeed overlaps with the session scope.
The difference is that the session scope is tied to the HTTP session, while @Stateful
is an open-ended user managed session, with its lifetime managed by a client that has a reference to the bean proxy.
@Stateful
remote beans where originally the binary (RMI) counter parts of Servlets. Where Servlets listened to remote HTTP requests from a browser, @Stateful
remote beans listened to remote RMI requests from Applets (and later Swing clients).
There were unfortunately many inconsistencies between the two. A Servlet was just an HTTP listener, while @Stateful
beans automatically brought in a lot of other features. A Servlet also shared the session with all other Servlets and also shared the Java EE component namespace with all other Servlets in a war, while with the @Stateful
EJB every separate bean has its own session and component namespace.
With the introduction of local beans in EJB 2 and a sharp decline of Swing/Applet clients for remote EJB communication, the function of the session that's maintained for an @Stateful
bean has become less clear.
I think it's fair to say that @Stateful
simply isn't used that much these days. For a web application the HTTP session is almost always leading, which means using the session scope and local @Stateless
beans and/or CDI beans for business logic.
In some cases @Stateful
beans are needed for their natural support for the extended persistence context from JPA and for their passivation features (Servlet doesn't have a standardized passivation mechanism). Note that @Stateful
and @SessionScoped
(or many other scopes) can be combined. The advantage of combining them is that user code no longer needs to manage the lifetime, but the container manages this.
There's a somewhat similar story for @ApplicationScoped
and @Singleton
, although without the legacy (@Singleton
is a fairly new thing). @ApplicationScoped
is just a scope, while @Singleton
is a bean type (stereotype if you wish), which doesn't only give you application scoped behavior, but also provides you with transactional behavior again, with automatic locking (which can be tuned via @Lock
) and with eager construction behavior (via @Startup
).
Although @Stateful
and @Singleton
are by themselves pretty handy, the current way forward in Java EE seems to be to decompose those build-in stereotypes into separately useable annotations and who knows, perhaps one day they will be actual CDI stereotypes consisting of those decomposed annotations.