users@jersey.java.net

Re: Injecting spring beans annotation based

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 17 Mar 2008 14:45:16 +0100

Hi Martin,

Why can't the registered Spring beans be injected into other things
using Spring-based mechanisms? I know that Guice has the @Injected
annotation, does Spring have a similar annotation? you can probably wire
things up in the app config but it is not as nice as an annotation.

The Injectable interface was really designed for "constant" Java types
rather than application defined types (and minimal way of performing
injection of a fixed set of common stuff without depending on an IoC
container). So i think it best to see if there is Spring-way before
making changes around support of this interface.

Paul.

Martin Grotzke wrote:
> Hi,
>
> I'm just playing around with jersey - it's very much fun! - and found
> the Injectable interface when I had a look into the the ServletContainer
> class. There is shown how HttpServletRequest etc. are made injectable,
> very nice and very easy!
>
> It's as easy to do this with spring beans - once one has the
> SpringServlet configured ([1]). Just define an annotation @SpringBean:
>
> @Target({TYPE, FIELD, METHOD})
> @Retention(RUNTIME)
> public @interface SpringBean {
>
> }
>
> then, in your SpringServlet implement a base SpringInjectable for
> springified beans:
>
> private abstract class SpringInjectable<V> extends Injectable<SpringBean, V> {
> public Class<SpringBean> getAnnotationClass() {
> return SpringBean.class;
> }
> }
>
> and finally register the spring beans you want to publish to your
> resources within a method like this (still in the SpringServlet):
>
> protected void initiate(ResourceConfig rc, WebApplication wa) {
> // get spring's applicationContext
> ApplicationContext springContext = WebApplicationContextUtils.
> getRequiredWebApplicationContext(getServletContext());
> // register your spring beans - this is new
> addInjectables( wa, springContext, SpringService1.class, SpringService2.class );
> // now let jersey do the rest
> wa.initiate(rc, new SpringComponentProvider(springContext));
> }
>
> private void addInjectables( WebApplication wa, final ApplicationContext springContext, Class<?> ... injectables ) {
> for ( final Class<?> injectable : injectables ) {
> wa.addInjectable( injectable, new SpringInjectable() {
>
> @Override
> public Object getInjectableValue( Annotation a ) {
> return springContext.getBean( getBeanName( injectable, springContext ) );
> }
>
> });
>
> }
> }
>
> This is very easy, just define an annotation and bind your source to it
> - really straightforward!
>
> Though, I really like inversion of control with the idea behind, that a
> class declares it's dependencies e.g. in a constructor, and these are
> the things where you have to know how this stuff works and what it does
> require, well...
>
> There's one shortcoming here - one has to know the classes that shall be
> made available to resources / for injection. It would be also nice to
> have some injectable provider that would be asked if there's an unknown
> type. Do you think this is desired?
>
> Cheers,
> Martin
>
>
> [1] http://blogs.sun.com/sandoz/entry/integrating_jersey_and_spring_take
>
>

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