@ServerEndpoint and @Autowired

11,735

Solution 1

It seems that you are trying to integrate Spring and Java WebSocket API. A class annotated by @Component is registered to a spring bean and its instance is managed by spring as a singleton by default. However, a class annotated by @ServerEndpoint is registered to a server-side WebSocket endpoint and every time the corresponding endpoint's WebSocket is connected to the server, its instance is created and managed by JWA implementation. Therefore, you can't use both annotations together.

Maybe the simplest workaround is to use CDI instead of Spring. Of course, your server should support CDI.

@ServerEndpoint("/ws")
public class MyWebSocket {   
    @Inject
    private ObjectMapper objectMapper;
}

If it's not feasible to you, you can intercept instantiation process of the class annotated with ServerEndpoint by using a your own version of 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 for integration with Spring).

Solution 2

This issue could be fixed using SpringConfigurator (spring 4):

Add configurator to your ServerEndpoint:

@ServerEndpoint(value = "/ws", configurator = SpringConfigurator.class)

required maven dependency:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>${spring.version}</version>
</dependency>

Solution 3

You should be able to just add this to your class actually.:

@PostConstruct
public void init(){
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}

Solution 4

My solution was:

public WebsocketServletTest() {
      SpringApplicationListener.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(this);
}

where SpringApplicationListener is a ApplicationContextAware, which stores the context in a static variable

Share:
11,735
arahant
Author by

arahant

SOreadytohelp

Updated on July 19, 2022

Comments

  • arahant
    arahant almost 2 years

    How can I autowire a field into a @ServerEndpoint. The following does not work.

    @Component
    @ServerEndpoint("/ws")
    public class MyWebSocket {   
        @Autowired
        private ObjectMapper objectMapper;
    }
    

    However if I remove the @ServerEndpoint, it works fine.

    I am using spring 3.2.1 and Java 7