Tuesday, November 4, 2008

Google Guice and jax-ws

To integrate google guice with jax-ws, you need to use the InstanceResolver extension point. this way your endpoints will look like this;

@GuiceManaged
@WebService(targetNamespace = "http://marcus", name="AddNumbers")
public class AddNumbersImpl {
  @Inject
  public void setCalculator(Calculator calc)
  {
      this.calculator=calc;
  }
...

To achieve this you need to create the annotation GuiceManaged;
@Retention(RUNTIME)
@Target(TYPE)
@Documented
@WebServiceFeatureAnnotation(id=GuiceManagedFeature.ID, bean=GuiceManagedFeature.class)
@InstanceResolverAnnotation(GuiceManagedInstanceResolver.class)
public @interface GuiceManaged {
}

Then you need to implement the GuiceManagedFeature:
public class GuiceManagedFeature extends WebServiceFeature {
    public static final String ID="some_nice_id";

    @FeatureConstructor
    public GuiceManagedFeature()
    {
        this.enabled=true;
    }
    
    public String getID() {
        return ID;
    }
}
And finally the actual InstanceResolver:
public class GuiceManagedInstanceResolver extends AbstractMultiInstanceResolver {
    private T instance=null;
    public GuiceManagedInstanceResolver(@NotNull Class clazz)
    {
        super(clazz);
    }
    public T resolve(@NotNull Packet packet) {
        if(instance==null)
        {
            instance=create();
            Injector injector= Guice.createInjector(new WebServiceModule());
            injector.injectMembers(instance);
        }
        return instance;
    }
}

That should do it, I'll update this post soon with a URL to the actual code (with documentation on how to use it. My plan is to make it more extensible (i.e. no hard dependency on the WebServiceModule) and possible to use in a non-singleton scope soon.

1 comment:

Dan Kaplan said...

Your instance resolver code doesn't compile. Can you fix this? Thanks