Tomcat8 WebSockets (JSR-356) 与 Guice 3.0

问题描述 投票:0回答:3

我正在尝试将 Guice 服务 @Inject 到 @ServerEndpoint 中。我使用 Tomcat 8.0.15 作为 JSR-356 实现。但是,依赖注入不起作用。为了启用 Guice 注入,是否需要完成任何额外的配置?请注意,我仅使用所有标准 javax 注释。

java websocket guice tomcat8 jsr356
3个回答
8
投票

我明白了这一点。 Websocket 端点需要有一个自定义配置器,它使用 Guice 注入器实例创建并返回实例。

示例:

自定义 Guice servlet 上下文监听器:

public class CustomServletContextListener extends GuiceServletContextListener { 
    public static Injector injector;

    @Override
    protected Injector getInjector() {
        injector = Guice.createInjector(...);
        return injector;
    }
}

Websockets 自定义配置器:

public class CustomConfigurator extends Configurator {
  @Override
  public <T> T getEndpointInstance(Class<T> clazz)
        throws InstantiationException {
    return CustomServletContextListener.injector.getInstance(clazz);
  }
}

然后在 Websocket 端点中:

@ServerEndpoint(value = "/ws/sample_endpoint", configurator = CustomConfigurator.class)
public class SampleEndpoint {
  private final SomeService service;

  @Inject
  public SampleEndpoint(SomeService service) {
    this.service = service;
  }
  ...
}

6
投票

基于 Aritra 自己的答案:

说实话,我不确定这是否适用于 Guice 3.0,但它确实适用于 4.0,这是当前的稳定版本。

我认为一种更干净的方法是将您的 CustomConfigurator 更改为如下所示:

public class CustomConfigurator extends Configurator {
    @Inject
    private static Injector injector;

    public <T> T getEndpointInstance(Class<T> endpointClass) {
        return injector.getInstance(endpointClass);
    }
}

然后从扩展的

ServletModule
类'
configureServlets
方法中,调用
requestStaticInjection(CustomConfigurator.class)

这样您就不会将注射器暴露给所有人。我不了解你的情况,但这给我一种美好而模糊的感觉,因为我知道没有人能够弄乱我的注射器:-)。


0
投票

首先,使用注释在幕后执行任何“魔法”是一个坏主意:最好使用

ServletContextListener.contextInitialized(event)
以编程方式部署端点,这样您就可以完全控制并且可以避免将注入器存储在静态上变量
.
现在关于注入,解决方案是定义您的自定义 ServerContainer.addEndpoint(config)

,如其他答案中所述,但是在 Endpoint 类中使用字段/setter 注入并调用

ServerEndpointConfig.Configurator

 后跟 
super.getEndpointInstance(endpointClass)
 会更安全。这是因为 
injector.injectMembers(endpointInstance)
 (给定容器的默认 
super
 impl)可能会返回容器特定的动态子类或包装新创建的 
Configurator
 实例的装饰器的实例。此外,规范要求 Endpoint 类具有无参数构造函数,因此某些容器可能拒绝部署使用构造函数注入的 Endpoint 类。
endpointClass


© www.soinside.com 2019 - 2024. All rights reserved.