jakarta.websocket.DeploymentException:Endpoint instance creation failed
错误信息:
解决方案:
要解决 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;@Overridepublic 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 BeanIatCapacity 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@OnOpenpublic void onOpen(Session session) {this.session = session;// 从 Spring 上下文获取 IatCapacityiat = SpringUtil.getBean(IatCapacity.class); // ... 其他初始化逻辑}// 其他方法(@OnMessage、@OnClose 等)...
}
逻辑总结
- 无参构造是必须的:WebSocket 容器强制要求,用于实例化。
- 放弃构造注入:WebSocket 容器不支持依赖注入,改用
SpringUtil
动态获取 Spring Bean。