[webbeans-dev] Creating instances of managed beans (including EJBs) in EE6 (was Re: non-contextual managed bean creation)
Kenneth Saks
Kenneth.Saks at Sun.COM
Thu Aug 13 12:03:07 EDT 2009
On Aug 13, 2009, at 10:51 AM, Pete Muir wrote:
>
> On 13 Aug 2009, at 15:19, Kenneth Saks wrote:
>
>>
>> On Aug 13, 2009, at 7:43 AM, Pete Muir wrote:
>>
>>> Here we need to address a slightly different aspect of managed bean
>>> lifecycles when CDI is enabled. This has the most impact on EJBs, as
>>> they are currently the only other direct instantiator of managed
>>> beans.
>>>
>>> After speaking to Gavin yesterday, and closely reading the latest
>>> CDI
>>> spec, I've noticed that CDI now expects EJB to delegate EJB instance
>>> creation to CDI, when CDI is enabled in the application. The reason
>>> for this is to allow EJBs to support constructor injection. IMO
>>> there
>>> are three extremely strong reasons why we need to support this:
>>>
>>> 1) Constructor injection is a (very) good thing, because it allows
>>> you
>>> to make a class fully immutable. This will make EJBs a more
>>> attractive
>>> programming model.
>>> 2) For a developer, it makes adding EJB services to your EJB (or
>>> removing them) more transparent as constructor injections don't have
>>> to be altered
>>> 3) it's required by the 330 and 299 specs
>>>
>>> CDI provides an SPI specifically for this purpose with
>>> InjectionTarget.produce(), so I propose we add a requirement that
>>> Web
>>> Beans integrators have their EJB container call
>>> injectionTarget.produce() when CDI is enabled in an application to
>>> create a bean instance.
>>>
>>> Clearly, an integrator wouldn't want to hardcode this into their EJB
>>> container, so a logical way to implement this would be for the EJB
>>> container to provide a (non-portable) SPI that defines lifecycle
>>> control for bean instances, along with a default implementation. The
>>> SPI could look something like this - default implementation also
>>> described:
>>
>> I think we'll also need to somehow capture the association to the
>> actual EJB component
>> (e.g. the corresponding org.jboss.webbeans.ejb.spi.EjbDescriptor),
>> since that can't
>> necessarily be derived from the bean class type alone.
>
> Yes, this would allow us to actually use the Bean instance rather than
> a generic InjectionTarget. We will need therefore to a Web Beans (not
> CDI) SPI for this:
>
> /**
> * Provides bean management above that which
> * is required by the spec
> */
> interface WebBeansManager {
> ....
>
> /**
> * Create an InjectionTarget for a session bean
> *
> * @param descriptor the container provided
> * EjbDescriptor to create the session
> * bean injection target
> */
> InjectionTarget createInjectionTarget(EjbDescriptor descriptor);
>
> }
>
> WDYT?
Looks good.
>
>>
>>>
>>> * newInstance() - create a new bean instance as required by EJB spec
>>> * inject() - perform Java EE style injection
>>> * postConstruct() - call the @PostConstruct method
>>> * preDestroy() - call the @PreDestroy method
>>
>> I agree we need newInstance() and inject(), but I'd rather not
>> delegate
>> the top-level postConstruct()/preDestroy() operations through the
>> SPI since it complicates
>> the case where there are EJB style (ejb-jar.xml / @Interceptors) and/
>> or CDI style interceptors
>> associated with the EJB component.
>
> Ok. This is clearly up to an integrator, if you can pass the 299 TCK
> like this, it will work great.
>
>> Let's add a web beans provided interceptor that the EJB container
>> will register after any
>> EJB-style interceptors. That can handle all interceptors that are
>> specified via
>> CDI-style metadata.
>
> I was just talking with Carlo about how to do this. Since we are now
> doing such deep integration, I would prefer to switch to using an SPI
> to specify the interceptors to apply to a session bean. Of course, the
> EJB container could choose to use an interceptor to attach them
> (essentially moving the built in SPI to the container). I guess such
> an SPI would look like [1]:
>
> interface EjbServices {
>
> ...
>
> void registerInterceptors(EjbDescriptor<?> descriptor,
> Collection<Interceptor<?>> interceptors);
> }
>
> This would completely remove the Web Beans built in EJB interceptor
> (more flexible for integrators).
Does this represent
a) the CDI impl's system-level interceptor
or
b) application-level interceptors that are specified via CDI-specific
metadata
Or are you saying there is no longer a need for a) ?
It's an important distinction since a) would need to be registered
before *any*
application-level interceptors, whereas b) would be registered after
interceptors
specified via the EJB interceptor metadata.
>
> [1] An alternative would be to make EjbDescriptor have a
> registerInterceptors method, but that means it is no longer just a
> descriptor, but something that can affect the EJB container. I don't
> like this so much.
> _______________________________________________
> webbeans-dev mailing list
> webbeans-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/webbeans-dev
More information about the weld-dev
mailing list