users@jersey.java.net

Re: Injecting spring beans annotation based

From: Martin Grotzke <martin.grotzke_at_javakaffee.de>
Date: Sun, 23 Mar 2008 18:27:21 +0100

On Wed, 2008-03-19 at 11:16 +0100, Paul Sandoz wrote:
> Martin Grotzke wrote:
> > Hi,
> >
> > On Mon, 2008-03-17 at 14:45 +0100, Paul Sandoz wrote:
> >> 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.
> > I think in spring 2.5 annotation-based DI has been improved
> > significantly. Though, we're still using spring 2.0 and do not use
> > spring annotations for wiring up beans, so I don't know what are all the
> > possibilities provided (just having a look at the spring docs shows that
> > e.g. the javax.annotation.Resource is supported).
> >
>
> OK. I thought Spring provides (or was going to provide) support for EE5.
Which parts of EE5 do you have in mind?

From the spring 2.5 announcement [1]:
- Full Java 6 and Java EE 5 support (JDBC 4.0, JTA 1.1, JavaMail 1.4,
JAX-WS 2.0)

More details on e.g. annotation based configuration or support for the
JSR-250 @Resource annotation can be found at [2] and [3], but I didn't
have the time to play with it.


> Spring or WebBeans (preferably WebBeans) will be the way we support
> EE5/EE6 stuff for Jersey so we don't have to implement it ourselves.
I'm not so comfortable with WebBeans, but after a very short look at the
jsr details it looks really promising!

> >> 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.
> > Alright. Though, it's really nice and easy and therefore was somehow an
> > invitation to use / play with it ;)
> >
>
> Great, it was a really nice surprise to see you doing that :-) i am glad
> it works for you.
>
> If we cannot find an alternative Spring way that is acceptable and the
> current approach starts to cause you pain we can look into changing the
> injectable behvaiour to support what you require.
Hmm, still not sure what would be the best approach...

>
> A question: Is Tapestry a bit like Wicket?
There are similarities but also big differences. AFAIK wicket creates
one component/page instance per request, whereas tapestry manages a pool
of page instances. Page instances are proxied and enhanced by tapestry,
and have a certain lifecycle. I'd say that a resource class probably
would not be a page class, but one might imagine that you return some
tapestry page from a resource method? Or specify a tapestry page as
result view that gets activated with the return value of the resource
method...
Just to mention it: I know nothing about jersey MVC (besides that you
can specify some @View that is probably using to forward to...?).

Cheers,
Martin


> Is it possible to merge
> Tapestry and Jersey together is anyway? for example, i am thinking if
> there is a connection to the basic-MVC stuff we put into Jersey, or if a
> resource class can also be a page?



[1] http://www.springframework.org/node/561
[2] http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config
[3] http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-resource-annotation

>
> Paul.
>
> >
> > Cheers,
> > Martin
> >
> >
> > [1] http://tapestry.apache.org/tapestry5/
> >
> >
> >> 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
> >>>
> >>>
>