在Web容器外的Java 6中使用Guice 3和JAX-WS

我们有一种情况,我们使用基于JSR-330的注入来配置我们的独立Java 6应用程序,这非常适合在所有层中获取配置参数。

我们还使用JAX-WS Web服务很长一段时间,在Web容器中使用Java 5的第一个独立Metro分发,但是使用Java 6我们只使用Endpoint类来减少占用空间。

所以现在我有一个情况

  • 一个独立的Java 6应用程序 – 没有servlet容器(Jetty,Tomcat)
  • Guice 3 Injector按照我喜欢的方式设置。
  • 处理我的@javax.jws.WebService注释类的Endpoint ,它将我的方法公开为Web服务。

我希望Web服务方法要么透明地处理它们的@Inject字段,要么访问注入器。 我可以从主方法中获取它作为静态字段,但我想要一个更清洁的解决方案。

有什么建议么?

(我从JAX-WS和Guice 3了解到http://jax-ws-commons.java.net/guice/模块不能与Guice 3一起使用,建议的解决方法是特定于Tomcat)

JSR-250 @Resource注释在这里有用吗?

我不确定我是否理解了所有问题。 它看起来太容易了+500赏金。 如果不是您要搜索的内容,请发布一些代码。

无论如何,一个简单的解决方案,创建一个dependency injection的Web服务:

 final Module module = new HelloModule(); final Injector injector = Guice.createInjector(module); final HelloService helloService = injector.getInstance(HelloService.class); Endpoint.publish("http://localhost:8080/helloService", helloService); 

下面是基于Marcus Eriksson的JAX-WS Guice集成代码的类路径扫描( Reflections )的更复杂的解决方案。 它使用Endpoint.publish()发布所有使用@GuiceManaged注释为Web服务的类。

 private void initGuicedWebservices(final String packageNamePrefix) throws Exception { final Reflections reflections = new Reflections(packageNamePrefix); final Set> guiceManaged = reflections.getTypesAnnotatedWith(GuiceManaged.class); for (final Class clazz : guiceManaged) { doGuice(clazz); } } private void doGuice(final Class clazz) throws Exception { final GuiceManaged guiceManagedAnnotation = clazz.getAnnotation(GuiceManaged.class); final Injector injector = createInjector(guiceManagedAnnotation); final Object serviceObject = clazz.newInstance(); injector.injectMembers(serviceObject); final String address = guiceManagedAnnotation.address(); Endpoint.publish(address, serviceObject); } private Injector createInjector(final GuiceManaged guiceManagedAnnotation) throws Exception { final Class[] moduleClasses = guiceManagedAnnotation.module(); final List moduleInstances = new ArrayList(); for (final Class moduleClass : moduleClasses) { moduleInstances.add(moduleClass.newInstance()); } return Guice.createInjector(moduleInstances); } 

GuiceManaged注释:

 @Retention(RUNTIME) @Target(TYPE) @Documented public @interface GuiceManaged { public Class[] module(); public String address(); } 

以及HelloServiceImpl片段:

 @GuiceManaged(module = HelloModule.class, address = "http://localhost:8080/helloService") @WebService public class HelloServiceImpl implements HelloService { @Inject // bound in HelloModule public GreetingsService greetingsService; @Override @WebMethod public String sayHello(final String name) { return greetingsService.sayHello(name); } } 

您需要使用AbstractMultiInstanceResolver扩展点。

创建注释GuiceManaged ;

 @Retention(RUNTIME) @Target(TYPE) @Documented @WebServiceFeatureAnnotation(id=GuiceManagedFeature.ID, bean=GuiceManagedFeature.class) @InstanceResolverAnnotation(GuiceManagedInstanceResolver.class) public @interface GuiceManaged { } 

实现GuiceManagedFeatureWebServiceFeature

 public class GuiceManagedFeature extends WebServiceFeature { public static final String ID="FEATURE_GuiceManaged"; @FeatureConstructor public GuiceManagedFeature() { this.enabled=true; } public String getID() { return ID; } } 

通过扩展AbstractMultiInstanceResolver实现InstanceResolver

 public class GuiceManagedInstanceResolver extends AbstractMultiInstanceResolver { private T instance=null; public GuiceManagedInstanceResolver(@NotNull Class clazz) { super(clazz); } public T resolve(@NotNull Packet request) { if(instance==null) { instance=create(); Injector injector= Guice.createInjector(new WebServiceModule()); injector.injectMembers(instance); } return instance; } } 

现在使用@GuiceManaged注释您的服务并使用@Inject在您的业务方法上使用方法级别DI。