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);
}