Doing it in the CDI container startup callbacks is not correct as the container is not
fully initialised. For Seam 3.0 you will need to use an EJB 3.1 singleton (which provides
an application startup callback), or listen to servlet callbacks (we may need to fix the
ordering of the Seam servlet listeners outside of JBoss AS/GF). Doing this through events
also addresses your "transient startup scope" as you can simply declare your
bean dependent, meaning it will be destroyed after the observer invocation is complete.
We should standardise the events sent so that they can be called outside of Servlet too.
What are they currently?
On 20 Oct 2010, at 05:05, Dan Allen wrote:
One of the popular features in the Seam 2 "container" is
startup components (which would be startup beans in CDI terminology). I'm trying to
determine the best way to approach this feature and where it should live (i.e., Weld X
and/or Seam 3, hence the x-post).
While it's true that EJB 3.1 supports startup beans, it unnecessarily links them to:
- enterprise beans (my, where have we heard this before? cough transactions cough)
- singletons
Seam 2 supports startup components that are instantiated (as in @PostConstruct gets
invoked) when the scope to which the component is bound is activated. Supported scopes
include application and session. I don't see any reason why we can't support all
(or most) scopes in Weld X/Seam 3.
At first glance, you might think about initializing @ApplicationScoped @Startup beans in
an AfterDeploymentValidation observer (the application-scope is active at that point) [1]
(also see note). That's certainly one way to go, though perhaps jumping the gun as
some other extensions may still report a deployment error. It also doesn't address the
remaining scopes.
The better place to do eager initialization is perhaps the Seam 3 Servlet module. This
module bridges the Servlet context events to the CDI event bus, providing the opportunity
to initialize components bound to the relevant scopes. However, my concern is that if
those events fire before the CDI implementation has started the scope, it's going to
result in a ContextNotActiveException (Nik, would you be able to provide insight into
whether this ordering issue has been address?).
I'd also like to entertain the idea of having a transient startup scope
(@ApplicationStartupScoped?). Most of the time developers employ a application-scoped
startup bean, it's doing something like seeding a database, creating directories or
some other routine that's a one time deal. It seems like a waste to have these beans
hang around long after their job is done. In fact, I anticipate it becoming the most
commonly-used scope for startup beans.
After considering the options, it seems to me that long-term, this feature would be more
robust if it were part of the CDI specification. (Even the JSF managed bean container
supports eager bean initialization for application-scoped beans). Or perhaps I'm
missing a very straightforward way to address it.
I'm interested in hearing your suggestions. After I get feedback about which
project/module should tackle this problem, I'll create a JIRA for it.
-Dan
[1]
http://gist.github.com/635719
Note: There's another issue. BeanManager#getReference() may only return a proxy and
not instantiate the bean, meaning @PostConstruct is not yet called. In the linked gist, I
worked around this problem by invoking toString() on the reference.
I'll mention that Resin has addressed @Startup support for managed beans:
http://caucho.com/resin-4.0/examples/ioc-binding/viewfile?file=WEB-INF/cl...
--
Dan Allen
Principal Software Engineer, Red Hat | Author of Seam in Action
Registered Linux User #231597
http://mojavelinux.com
http://mojavelinux.com/seaminaction
http://www.google.com/profiles/dan.j.allen
_______________________________________________
weld-dev mailing list
weld-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/weld-dev