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

发布于 2024-12-08 16:22:00 字数 831 浏览 0 评论 0原文

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

我们还使用 JAX-WS Web 服务相当长一段时间,通过在 Web 容器内使用第一个独立的 Metro 发行版和 Java 5,但在 Java 6 中,我们只使用 Endpoint 类来获得更小的占用空间。

所以现在我遇到的情况是,我有

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

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

有什么建议吗?

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

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

We have a situation where we use JSR-330 based injections to configure our stand-alone Java 6 applications, which works very well for getting configuration parameters across all the layers.

We have also used JAX-WS web services for quite a while by using first stand-alone Metro distribution with Java 5 inside a web container, but with Java 6 we just use the Endpoint class to get a smaller footprint.

So now I have a situation where I have

  • A stand-alone Java 6 application - no servlet container (Jetty, Tomcat)
  • A Guice 3 Injector set up as I like it.
  • An Endpoint handling my @javax.jws.WebService annotated class which expose my methods as web services.

I would like the web service methods to either have their @Inject fields handled transparently, or to get access to the injector. I can grab it as a static field from the main method, but I'd like a cleaner solution.

Any suggestions?

(I understand from JAX-WS and Guice 3 that the http://jax-ws-commons.java.net/guice/ module does not work with Guice 3, and the workaround suggested is Tomcat specific)

Would JSR-250 @Resource annotations be useful here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

溇涏 2024-12-15 16:22:00

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

不管怎样,一个简单的解决方案创建了一个带有依赖注入的网络服务:

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);

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

private void initGuicedWebservices(final String packageNamePrefix) 
        throws Exception {
    final Reflections reflections = new Reflections(packageNamePrefix);
    final Set<Class<?>> 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<? extends Module>[] moduleClasses = 
        guiceManagedAnnotation.module();

    final List<Module> moduleInstances = new ArrayList<Module>();
    for (final Class<? extends Module> moduleClass : moduleClasses) {
        moduleInstances.add(moduleClass.newInstance());
    }

    return Guice.createInjector(moduleInstances);
}

GuiceManaged 注释:

@Retention(RUNTIME)
@Target(TYPE)
@Documented
public @interface GuiceManaged {
    public Class<? extends Module>[] 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);
    }
}

I'm not sure that I've understood every bit of the question. It looks to too easy for +500 bounty. Please post some code if that's not what you're searching for.

Anyway, a simple solution which creates a web service with dependency injection:

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);

Below a more sophisticated solution with classpath scanning (Reflections) based on Marcus Eriksson's code from JAX-WS Guice integration. It publishes all classes which is annotated with @GuiceManaged as a webservice with Endpoint.publish().

private void initGuicedWebservices(final String packageNamePrefix) 
        throws Exception {
    final Reflections reflections = new Reflections(packageNamePrefix);
    final Set<Class<?>> 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<? extends Module>[] moduleClasses = 
        guiceManagedAnnotation.module();

    final List<Module> moduleInstances = new ArrayList<Module>();
    for (final Class<? extends Module> moduleClass : moduleClasses) {
        moduleInstances.add(moduleClass.newInstance());
    }

    return Guice.createInjector(moduleInstances);
}

The GuiceManaged annotation:

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

And the HelloServiceImpl snippet:

@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);
    }
}
回首观望 2024-12-15 16:22:00

您需要使用 AbstractMultiInstanceResolver 扩展点。

创建注释GuiceManaged

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

实现 GuiceManagedFeature ,即 WebServiceFeature

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。

you need to use the AbstractMultiInstanceResolver extension point.

create the annotation GuiceManaged;

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

implement the GuiceManagedFeature which is WebServiceFeature :

public class GuiceManagedFeature extends WebServiceFeature {
    public static final String ID="FEATURE_GuiceManaged";

    @FeatureConstructor
    public GuiceManagedFeature()
    {
        this.enabled=true;
    }

    public String getID() {
        return ID;
    }
}

Implement InstanceResolver by Extending AbstractMultiInstanceResolver

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;
    }
}

Now Annotate your Service with @GuiceManaged & use @Inject for method level DI on your business method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文