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;
}
...
}
3条答案
按热度按时间bq3bfh9z1#
我想明白了WebSocket端点需要有一个自定义配置器,它使用Guice注入器示例创建并返回示例。
范例:
自定义Guice servlet上下文侦听器:
Websockets自定义配置器:
然后在WebSocket端点中:
cld4siwp2#
根据Aritra自己的回答:
老实说,我不确定这是否适用于Guice 3.0,但它确实适用于4.0,这是当前的稳定版本。
我认为一个更干净的方法是将您的Customerator更改为这样:
然后从扩展
ServletModule
类的configureServlets
方法中调用requestStaticInjection(CustomConfigurator.class)
,这样你就不会把注射器暴露给所有人我不知道你,但它给了我一个很好的和模糊的感觉里面知道,没有人将能够与我的注射器混乱:-).
rbl8hiat3#
首先,使用注解在幕后做任何“魔术”通常是一个坏主意:在
ServletContextListener.contextInitialized(event)
中使用ServerContainer.addEndpoint(config)
以编程方式部署Endpoints
要好得多,这样您就可以完全控制,并且可以避免将injector存储在静态vars上。现在关于注入,解决方案是定义你的自定义
ServerEndpointConfig.Configurator
,就像在其他答案中已经提到的那样,但是在Endpoint
类中使用字段/setter注入并调用super.getEndpointInstance(endpointClass)
然后调用injector.injectMembers(endpointInstance)
要安全得多。这是因为super
(给定容器的默认Configurator
impl)可能会返回特定于容器的动态子类或装饰器的示例,这些子类或装饰器 Package 了新创建的endpointClass
示例。此外,规范要求Endpoint
类具有无参数构造函数,因此某些容器可能会拒绝部署使用构造函数参数进行注入的Endpoint
类。现在,
SevletContextListener
以编程方式添加Endpoints
:请注意,如果您要进行编程添加,您的
Endpoint
类应该根据规范扩展javax.websocket.Endpoint
/jakarta.websocket.Endpoint
(尽管AFAIR Tomcat特别放松了这一要求)。一些相关的自我推销:对于任何将guice与websockets相结合的人来说,你可能会发现有用的my lib,它为ws
Endpoints
提供了自定义Scopes
:https://github.com/morgwai/servlet-scopes