question
This problem is mainly caused by the way Websocket works. Here are the detailed solutions
solve
The reason WebSocket endpoint classes are usually not managed by Spring IOC is that they are managed by WebSocket containers (for example, Tomcat, Jetty, etc.) rather than Spring containers.
The WebSocket specification (JSR 356) defines the life cycle and management of WebSocket endpoints, which is usually different from Spring's life cycle and dependency injection mechanisms.
Here are some specific reasons and solutions:
reason
Different life cycle management:
- The creation and management of WebSocket endpoints are handled by web containers (such as Tomcat, Jetty, etc.), rather than by Spring containers.
- This means that the instantiation and lifecycle management of the WebSocket endpoint class are not within Spring's control scope.
Different injection mechanisms:
- Spring's dependency injection mechanism relies on Spring container-managed beans, but when the WebSocket endpoint class is instantiated, the Web container does not know how to perform dependency injection.
Solution
Method 1: Use Spring Boot and @Configuration to configure
In Spring Boot projects, you can manage WebSocket connections by configuring classes and customizing WebSocket processors, which allows you to use Spring container-managed beans.
Create a WebSocket configuration class:
import ; import ; import ; import ; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { private final MyWebSocketHandler myWebSocketHandler; public WebSocketConfig(MyWebSocketHandler myWebSocketHandler) { = myWebSocketHandler; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { (myWebSocketHandler, "/websocket").setAllowedOrigins("*"); } }
Create a WebSocket Processor Class:
import ; import ; import ; import ; @Component public class MyWebSocketHandler extends TextWebSocketHandler { private final SomeService someService; public MyWebSocketHandler(SomeService someService) { = someService; } @Override public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = (); ("The message is:" + payload); (); // Use Spring Bean (new TextMessage("servet send:" + payload)); } }
Method 2: Use custom SpringConfigurator
Create a custom oneSpringConfigurator
:
import ; import ; import ; public class SpringConfigurator extends { @Override public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException { WebApplicationContext context = (); if (context == null) { throw new InstantiationException("Unable to get Spring context."); } return ().createBean(clazz); } }
exist@ServerEndpoint
Specified in the annotationconfigurator
:
import ; import ; import ; import ; @ServerEndpoint(value = "/websocket", configurator = ) @Component public class MyWebSocket { @Autowired private SomeService someService; // Bean managed by Spring @OnMessage public String onMsg(String text) throws IOException { ("The message is:" + text); (); // Use Spring Bean return "servet send:" + text; } }
Method 3: Manually obtain Spring Bean
Create ApplicationContextProvider class:
import ; import ; import ; @Component public class ApplicationContextProvider implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) { context = applicationContext; } public static ApplicationContext getApplicationContext() { return context; } }
Get Beans using ApplicationContextProvider in WebSocket class:
import ; import ; import ; @ServerEndpoint(value = "/websocket") @Component public class MyWebSocket { private SomeService someService; public MyWebSocket() { = ().getBean(); } @OnMessage public String onMsg(String text) throws IOException { ("The message is:" + text); (); // Use Spring Bean return "servet send:" + text; } }
With these methods, you can ensure that the WebSocket endpoint class correctly accesses beans managed by Spring IOC, thus avoiding null pointer exceptions.
Summarize
The above is personal experience. I hope you can give you a reference and I hope you can support me more.