[webbeans-dev] Creating instances of managed beans (including EJBs) in EE6 (was Re: non-contextual managed bean creation)

Pete Muir pmuir at redhat.com
Thu Aug 13 10:51:14 EDT 2009


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?

>
>>
>> * 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).

[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.



More information about the weld-dev mailing list