users@jersey.java.net

Re: [Jersey] Simplifying Jersey life-cycle and IoC integration

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 27 Oct 2008 12:40:29 +0100

On Oct 27, 2008, at 12:14 PM, Martin Grotzke wrote:

> Hi Paul,
>
> sounds good to me. Do you plan to change the spring-stuff together
> with
> the api/interface changes, or can I help in this area?
>

Yes, just committed the code :-) no test failures. I don't recall if
we have any tests for AOP-based stuff, if we do not it might be useful
to add something.

One area that could be improved is this:

         if (springContext.isSingleton(beanName)) {
             return new
SpringManagedComponentProvider(ComponentScope.Singleton, beanName, c);
         } else if (springContext.isPrototype(beanName)) {
             return new
SpringManagedComponentProvider(ComponentScope.PerRequest, beanName, c);
         } else {
             return new
SpringManagedComponentProvider(ComponentScope.Undefined, beanName, c);
         }

For the ComponentScope.PerRequest we could support Spring "prototype"
or the Spring "per-request" scope. I seem to recall that you defined a
mapping from Jersey scopes and Spring scopes that allowed for the "per-
request" inclusion. Was that right?

BTW the new approach should be a little more efficient as the spring
bean name does not need to be derived each and every time an instance
is requested.

Paul.

> Cheers,
> Martin
>
>
> On Thu, 2008-10-23 at 12:15 +0200, Paul Sandoz wrote:
>> Hi,
>>
>> It is clear that the integration of IoC frameworks is more
>> complicated
>> that it should be, especially when the Jersey life-cycle annotations
>> need to sync up with the IoC life-cycles.
>>
>> I propose the following simplifications:
>>
>> 1) Jersey should get out of the way when an IoC integrates such that
>> Jersey always defers the IoC life-cycle
>> mechanisms of the IoC. The Jersey specific life-cycle
>> annotations should only be used when an IoC such as
>> Spring, Guice or WebBeans is not integrated. Of course this does
>> not mean that someone could write their
>> own special IoC that re-used Jersey's life-cycle support (e.g.
>> for proxies of components) or an IoC integration
>> could provide some support for transitioning to the IoC.
>>
>> 2) Jersey should never defer to an IoC (if present) for the
>> instantiation of internal Jersey components.
>>
>> 3) Unify ResourceProvider/ResourceProviderFactory with
>> ComponentProvider and clearly differentiate
>> between Jersey and IoC component providers.
>>
>> The proposed interfaces for 3) are at the end of the email. There are
>> specifics to IoC integration that Jersey needs to know if it has to
>> perform injection of Jersey specific artifacts (if the IoC does not
>> support this). The interface IoCComponentProvider represents those
>> specifics.
>>
>> The Jersey life-cycle annotations will declare specific
>> ComponentProvider classes.
>>
>> @Target({ElementType.TYPE})
>> @Retention(RetentionPolicy.RUNTIME)
>> @Documented
>> @ResourceProvider(PerRequestComponentProvider.class)
>> public @interface PerRequest {}
>>
>> This should also make the integration with an IoC a little more
>> efficient since validation can be performed once by the
>> ComponentProvider and not each and every time an instance is
>> requested.
>>
>> Paul.
>>
>> /**
>> * A factory for obtaining component providers
>> */
>> interface ComponentProviderFactory<C extends ComponentProvider> {
>>
>> /**
>> * Get the component provider for a class.
>> *
>> * @param c the class
>> * @return the component provider for the class
>> */
>> C getComponentProvider(Class c);
>>
>> /**
>> * Get the component provider for a class.
>> *
>> * @param cc the component context to obtain annotations and
>> * annotated object (if present).
>> * @param c the class
>> * @return the component provider for the class
>> */
>> C getComponentProvider(ComponentContext cc, Class c);
>> }
>>
>>
>> /**
>> * Provide instances of a component.
>> *
>> */
>> interface ComponentProvider {
>> /**
>> * Get the instance.
>> *
>> * @return the instance.
>> */
>> Object getInstance();
>> }
>>
>> /**
>> * An IoC-specific factory for obtaining IoC-specific component
>> providers.
>> *
>> */
>> interface IoCComponentProviderFactory extends
>> ComponentProviderFactory<IoCComponentProvider> {
>> }
>>
>>
>> /**
>> * Provide instances of a IoC-specfic component.
>> *
>> */
>> interface IoCComponentProvider extends ComponentProvider {
>> /**
>> * Get the scope.
>> * <p>
>> * The Scope is required so that Jersey can correctly inject on
>> an instance
>> * returned from an application specfic component provider.
>> *
>> * @return the scope
>> */
>> Scope getScope();
>>
>> /**
>> * Get the injectable instance that Jersey can perform field and
>> method
>> * setter injection on.
>> *
>> * @param o the instance returned from getInstance.
>> * @return the injectable instance. May be the same as o. If null
>> * then Jersey will perform no injection.
>> */
>> Object getInjectableInstance(Object o);
>> }
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
> --
> Martin Grotzke
> http://www.javakaffee.de/blog/