users@jersey.java.net

Re: Injecting spring beans annotation based

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 18 Mar 2008 11:26:56 +0100

Hi Martin,

In relation to this you might want to check out a blog comment from James:

http://blogs.sun.com/sandoz/entry/integrating_jersey_and_spring_take#comment-1205397278000

it is using the Spring auto-wiring feature (if a bean is not registered
in the XML config). Perhaps this may do what you require without having
to create your own annotation?

Paul.

Paul Sandoz wrote:
> 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