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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/webbeans-dev