@ServerEndpoint 和@Autowired
@ServerEndpoint and @Autowired
如何将字段自动连接到@ServerEndpoint。以下不起作用。
@Component
@ServerEndpoint("/ws")
public class MyWebSocket {
@Autowired
private ObjectMapper objectMapper;
}
但是,如果我删除 @ServerEndpoint
,它会正常工作。
我正在使用 spring 3.2.1 和 Java 7
JavaEE 7 规范说
@ServerEndpoint
The annotated class must have a public no-arg constructor.
看来您正在尝试集成 Spring 和 Java WebSocket API。由 @Component
注释的 class 被注册到 spring bean 并且其实例默认由 spring 作为单例管理。但是,由 @ServerEndpoint
注释的 class 注册到服务器端 WebSocket 端点,每次相应端点的 WebSocket 连接到服务器时,它的实例都由 JWA 实现创建和管理。因此,您不能同时使用这两个注释。
也许最简单的解决方法是使用 CDI 而不是 Spring。当然,你的服务器要支持CDI。
@ServerEndpoint("/ws")
public class MyWebSocket {
@Inject
private ObjectMapper objectMapper;
}
如果这对您不可行,您可以通过使用您自己的 ServerEndpointConfig.Configurator. Then, you can instantiate the class by yourself and autowire it using an instance of BeanFactory
or ApplicationContext
. Actually, there is already similar answer to this usage. See that question and Martins' working example (Especially, a customized Configurator 版本与 [=28= 集成来拦截用 ServerEndpoint
注释的 class 的实例化过程]).
您实际上应该可以将此添加到您的 class。:
@PostConstruct
public void init(){
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
可以使用 SpringConfigurator (spring 4) 解决此问题:
将配置器添加到您的 ServerEndpoint:
@ServerEndpoint(value = "/ws", configurator = SpringConfigurator.class)
需要 Maven 依赖项:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
我的解决方案是:
public WebsocketServletTest() {
SpringApplicationListener.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(this);
}
其中SpringApplicationListener是一个ApplicationContextAware,它将上下文存储在一个静态变量中
如何将字段自动连接到@ServerEndpoint。以下不起作用。
@Component
@ServerEndpoint("/ws")
public class MyWebSocket {
@Autowired
private ObjectMapper objectMapper;
}
但是,如果我删除 @ServerEndpoint
,它会正常工作。
我正在使用 spring 3.2.1 和 Java 7
JavaEE 7 规范说
@ServerEndpoint
The annotated class must have a public no-arg constructor.
看来您正在尝试集成 Spring 和 Java WebSocket API。由 @Component
注释的 class 被注册到 spring bean 并且其实例默认由 spring 作为单例管理。但是,由 @ServerEndpoint
注释的 class 注册到服务器端 WebSocket 端点,每次相应端点的 WebSocket 连接到服务器时,它的实例都由 JWA 实现创建和管理。因此,您不能同时使用这两个注释。
也许最简单的解决方法是使用 CDI 而不是 Spring。当然,你的服务器要支持CDI。
@ServerEndpoint("/ws")
public class MyWebSocket {
@Inject
private ObjectMapper objectMapper;
}
如果这对您不可行,您可以通过使用您自己的 ServerEndpointConfig.Configurator. Then, you can instantiate the class by yourself and autowire it using an instance of BeanFactory
or ApplicationContext
. Actually, there is already similar answer to this usage. See that question and Martins' working example (Especially, a customized Configurator 版本与 [=28= 集成来拦截用 ServerEndpoint
注释的 class 的实例化过程]).
您实际上应该可以将此添加到您的 class。:
@PostConstruct
public void init(){
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
可以使用 SpringConfigurator (spring 4) 解决此问题:
将配置器添加到您的 ServerEndpoint:
@ServerEndpoint(value = "/ws", configurator = SpringConfigurator.class)
需要 Maven 依赖项:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
我的解决方案是:
public WebsocketServletTest() {
SpringApplicationListener.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(this);
}
其中SpringApplicationListener是一个ApplicationContextAware,它将上下文存储在一个静态变量中