SoFunction
Updated on 2025-05-15

Springboot uses Websocket to call IOC managed beans to report null pointer exception

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@ServerEndpointSpecified 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.