users@jersey.java.net

Re: [Jersey] Guice in 0.8

From: Martin Grotzke <martin.grotzke_at_freiheit.com>
Date: Sun, 18 May 2008 18:21:41 +0200

Hi Zach,

just to mention - I have no clue how guice works. :)

But I'd say that you don't need an extra annotation @MyAnnotation but
you can refer directly @Named:

    @Override
    protected void initiate( ResourceConfig rc, WebApplication wa ) {
        super.initiate( rc, wa );

        wa.addInjectable(new Injectable<Named, Object>() {
            @Override
            public Object getInjectableValue(Object o, Field f, Named a)
                Injector injector = ...;
                return injector.getInstance(Key.get(f.getType(),
                     Names.named( a.value() ));
            }

            @Override
            public Class<Named> getAnnotationClass() {
                return Named.class;
            }
        });
    }

With this you can have fields of different types and your specific
names, e.g.:


@Named("something")
private Processor processor;

@Named("username")
private String username;

@Named("password")
private String password;

I'm not really sure, but AFAICS you also don't need a specific
ComponentProvider with this.


Cheers,
Martin


On Sun, 2008-05-18 at 11:35 -0400, Zach Cox wrote:
> Hi Martin,
>
> Injectable definitely seems useful! So in my use case, I need to
> inject a named Processor instance which I'd usually do in Guice like
> this:
>
> Where it needs to be injected:
>
> @Inject
> @Named("something")
> private Processor processor;
>
> In my AbstractModule subclass:
>
> bind(Processor.class).annotatedWith(Names.named("something")).to(ProcessorImpl.class);
>
> So in Jersey would I do something like this?
>
> Where it needs to be injected:
>
> @MyAnnotation
> private Processor processor;
>
> In my ServletContainer subclass:
>
> public class MyServletContainer extends ServletContainer {
>
> @Override
> protected void initiate( ResourceConfig rc, WebApplication wa ) {
> super.initiate( rc, wa );
>
> wa.addInjectable(new Injectable<MyAnnotation, Processor>() {
> @Override
> public Processor getInjectableValue(Object o, Field f,
> MyAnnotation a)
> Injector injector = ...;
> return injector.getInstance(Key.get(Processor.class,
> Names.named("something"));
> }
>
> @Override
> public Class<MyAnnotation> getAnnotationClass() {
> return MyAnnotation.class;
> }
> });
> }
>
> @Target({FIELD, PARAMETER, CONSTRUCTOR })
> @Retention(RUNTIME)
> @Documented
> public static @interface MyAnnotation {
>
> }
>
> }
>
>
> Thanks,
> Zach
>
>
> On Sun, May 18, 2008 at 11:17 AM, Martin Grotzke
> <martin.grotzke_at_freiheit.com> wrote:
> > Hi Zach,
> >
> > it sounds as if a feature introduced together with the
> > spring-integration would be useful for you.
> > I just wrote a short posting about this [1], but I also want to document
> > these DI-related features in the wiki - still on my TODO-list :)
> >
> > Cheers,
> > Martin
> >
> >
> > [1] http://www.javakaffee.de/blog/2008/05/18/jersey-di-use-custom-annotations-for-dependency-injection-in-your-resource-classes/
> >
> >
> > On Sun, 2008-05-18 at 09:25 -0400, Zach Cox wrote:
> >> Hi Paul,
> >>
> >> Thanks for the pointers! Here's what I've done so far (I'll post code
> >> once it's all working):
> >> - GuiceComponentProvider implements ComponentProvider
> >> - getInstance(Scope, Class<T>) uses Injector.getInstance method to
> >> create the object
> >> - inject(Object) uses Injector.injectMembers to inject members of the object
> >> - GuiceServlet extends ServletContainer
> >> - initiate(ResourceConfig, WebApplication) creates
> >> GuiceComponentProvider & passes it to WebApplication.initiate
> >> - web.xml
> >> - <servlet-class>com.whatever.GuiceServlet</servlet-class>
> >>
> >> With Guice, you can annotate the injected members, which is really
> >> convenient for commonly used types for which you need different
> >> instances injected in different places (like Strings).
> >>
> >> In some class that needs a username & password injected:
> >>
> >> @Inject
> >> @Named("username")
> >> private String username;
> >>
> >> @Inject
> >> @Named("password")
> >> private String password;
> >>
> >> In your AbstractModule subclass:
> >>
> >> bindConstant().annotatedWith(Names.named("username")).to("scuba");
> >> bindConstant().annotatedWith(Names.named("password")).to("steve");
> >>
> >> I actually need to annotate one of the fields to be injected by
> >> GuiceComponentProvider similar to the above. Is this possible using
> >> the ComponentProvider.getInstance(Scope, Class<T>) method? I'm not
> >> sure how to discover the @Named annotation and pass that info along to
> >> Guice.
> >>
> >> Thanks,
> >> Zach
> >>
> >>
> >> On Thu, May 15, 2008 at 12:45 PM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
> >> > Hi Zach,
> >> >
> >> > Zach Cox wrote:
> >> >>
> >> >> I found Christian Rivasseau's great work on Guice + Jersey:
> >> >>
> >> >>
> >> >> http://objectif-naiade.blogspot.com/2007/11/integrating-jersey-with-guice-and.html
> >> >>
> >> >> But that code was written back in Nov 2007 and the ResourceProvider
> >> >> interface is much different now in 0.8. Is there any code around to
> >> >> easily use Guice to inject field/method parameters in resource classes
> >> >> in 0.8? Or are there any tutorials/code examples I could study to
> >> >> create Guice integration in 0.8?
> >> >>
> >> >
> >> > If you are familiar with Guice, perhaps looking at a WebBeans example might
> >> > help [1].
> >> >
> >> > Plus you can look at the Spring code here [2].
> >> >
> >> > Things have changed to use the ComponentProvider interface. You can probably
> >> > hack things together to get things working by just implementing the
> >> > ComponentProvider.getInstance() method:
> >> >
> >> >
> >> > public static class GuiceComponentProvider
> >> > implements ComponentProvider {
> >> >
> >> > public <T> T getInjectableInstance( T instance ) {
> >> > return instance;
> >> > }
> >> >
> >> > public SpringComponentProvider(
> >> > ConfigurableApplicationContext springContext) {
> >> > this.springContext = springContext;
> >> > }
> >> >
> >> > public <T> T getInstance( Scope scope, Class<T> clazz )
> >> > throws InstantiationException, IllegalAccessException {
> >> >
> >> > // Insert Guice specific code here to get the instance
> >> > }
> >> >
> >> > public <T> T getInstance(Scope scope,
> >> > Constructor<T> constructor,
> >> > Object[] parameters)
> >> > throws InstantiationException, IllegalArgumentException,
> >> > IllegalAccessException, InvocationTargetException {
> >> > return getInstance(scope, constructor.getDeclaringClass());
> >> > }
> >> >
> >> > public void inject(Object instance) {
> >> > }
> >> > }
> >> >
> >> > Paul.
> >> >
> >> > [1]
> >> > http://stephan.reposita.org/archives/2008/02/25/adding-web-beans-jsr-299-to-jersey-for-rest/
> >> > [2]
> >> > https://jersey.dev.java.net/source/browse/*checkout*/jersey/trunk/contribs/spring/src/main/java/com/sun/jersey/spi/spring/container/servlet/SpringServlet.java?rev=998
> >> >
> >> >
> >> > --
> >> > | ? + ? = To question
> >> > ----------------\
> >> > Paul Sandoz
> >> > x38109
> >> > +33-4-76188109
> >> >
> >> > ---------------------------------------------------------------------
> >> > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> >> > For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >> >
> >> >
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> >> For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net