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