错误信息:
解决方案:
要解决 WebSocket 端点无法实例化(因构造方法问题),同时保留初始化逻辑,需按以下步骤调整:
核心问题分析
WebSocket 容器(如 Tomcat)要求 @ServerEndpoint
类必须有 公共无参构造(用于创建实例),但我的代码上:
- 标注了
@Component
(让 Spring 管理),但 WebSocket 容器和 Spring 会冲突创建实例; - 依赖
IatCapacity
通过构造方法注入,但 WebSocket 容器无法提供该参数(非 Spring 上下文)。
正确调整方案
1. 动态获取 IatCapacity
(替代构造注入)
因 WebSocket 容器不支持构造注入,需运行时从 Spring 上下文获取 IatCapacity
:
步骤 A:创建 Spring 上下文工具类
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component // 必须由 Spring 托管
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return context.getBean(clazz);
}
}
步骤 B:在 ASRWebsocketServer
中动态获取 IatCapacity
在需要使用 IatCapacity
的地方(如 @OnOpen
、业务方法),通过 SpringUtil
获取:
@OnOpen
public void onOpen(Session session) {
// 动态获取 Spring 管理的 IatCapacity Bean
IatCapacity iat = SpringUtil.getBean(IatCapacity.class);
this.iat = iat; // 赋值给成员变量
// ... 其他初始化逻辑
}
4. 完整代码示例
@Slf4j
@Component
@ServerEndpoint("/iat")
public class ASRWebsocketServer {
private Session session;
private static IatCapacity iat = null;
// 2. 连接建立时动态获取 Bean
@OnOpen
public void onOpen(Session session) {
this.session = session;
// 从 Spring 上下文获取 IatCapacity
iat = SpringUtil.getBean(IatCapacity.class);
// ... 其他初始化逻辑
}
// 其他方法(@OnMessage、@OnClose 等)...
}
逻辑总结
- 无参构造是必须的:WebSocket 容器强制要求,用于实例化。
- 放弃构造注入:WebSocket 容器不支持依赖注入,改用
SpringUtil
动态获取 Spring Bean。