Reputation: 2203
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
Upvotes: 6
Views: 13280
Reputation: 14863
My solution was:
public WebsocketServletTest() {
SpringApplicationListener.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(this);
}
where SpringApplicationListener is a ApplicationContextAware, which stores the context in a static variable
Upvotes: 1
Reputation: 211
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>
Upvotes: 6
Reputation: 9781
You should be able to just add this to your class actually.:
@PostConstruct
public void init(){
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
Upvotes: 5
Reputation: 1131
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).
Upvotes: 8
Reputation: 149
JavaEE 7 specification says
@ServerEndpoint
The annotated class must have a public no-arg constructor.
Upvotes: 0