users@jersey.java.net

ComponentProvider <was> Re: Injection of message body readers/writers now supported in latest builds

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 31 Jan 2008 11:33:51 +0100

Paul Sandoz wrote:
> And after that: enable deferring instantiation of readers/writers/jaxb
> resolvers/resource config etc to an IoC framework.
>

Mostly done, need to investigate how best enable plug in of an IoC
framework using a ComponentProvider implementation.

Every component is now instantiated using the ComponentProvider
interface. A default implementation is provided as part of the Web
application. This means that injection is uniformly supported on
components such a ResourceProvider and MessageBodyReader/Writer. Thus
one can inject ServletContext or say ResourceConfig on such instances
like one can do on root resource classes.

The ResourceProvider interface has been simplified and uses
ComponentProvider.

It should still be possible to write an IoC specific ResourceProvider as
follows (note i have not tested it):

   public class SpringProvider implements ResourceProvider {

     @Resource
     private ServletContext servletContex;
     private ApplicationContext springContext;
     private Object singletonResource;

     public void init(ComponentProvider provider,
         AbstractResource abstractResource) {

         springContext = WebApplicationContextUtils.
             getRequiredWebApplicationContext(servletContext);
         String names[] = springContext.
             getBeanNamesForType(abstractResource.getResourceClass());
         if (names.length == 0)
             throw new RuntimeException("No configured bean for "
                 + resourceClass.getName());
         else if (names.length > 1)
             throw new RuntimeException("Multiple configured beans for "
                 + resourceClass.getName());
         beanName=names[0];
         if (springContext.isSingleton(beanName)) {
              singletonResource = springContext.getBean(beanName,
                  resourceClass);
              provider.inject(singletonResource);
         }

     }

     public Object getInstance(ComponentProvider provider,
         HttpRequestContext request) {

       if (singletonResource != null)
         return singletonResource;
       else {
         Object resource = springContext.getBean(beanName,
             resourceClass);
         provider.inject(resource);
         return resource;
       }
     }
   }


Moving forward i think the right way to do this is to make the
life-cycle of resource classes more portable, use the existing support
in Jersey for per-request and singleton [*], and defer to say a
Spring-based ComponentProvider. This also means that other Jersey-based
components can particpate with Spring as well.

Paul.

[*] there is a caveat mentioned in Marc's blog [1] on constructors for
per-request life-cycle that is not resolved.

[1]
http://weblogs.java.net/blog/mhadley/archive/2007/09/integrating_jer.html

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109