Java Spring-boot - How to use @Autowired with @ServerEndpoint?

Vino :

I know there are lot of questions on this topic. I have read the spring boot doc and all of the solutions here. According spring boot doc, @ServerEndpoint is a Javax annotation and @Autowired components are spring-boot managed. These two cannot be used together. The solution to this would be to add SpringConfigurator as configurator of the ServerEndpoint. When I tried this I do get the following error:

Failed to find the root WebApplicationContext. Was ContextLoaderListener not used?

There is no example in the spring-boot websocket page to use ContextLoaderListener. How can use ContextLoaderListener so that components can be injected into @ServerEndpoint annotated controllers?

The following is my code.

Websocket controller

@ServerEndpoint(value = "/call-stream", configurator = SpringConfigurator.class)
public class CallStreamWebSocketController
{  
    @Autowired
    private IntelligentResponseService responseServiceFacade;

    // Other methods
}

Websocket configurations

@Configuration
public class WebSocketConfiguration
{
    @Bean
    public CallStreamWebSocketController callStreamWebSocketController()
    {
        return new CallStreamWebSocketController();
    }

    @Bean
    public ServerEndpointExporter serverEndpointExporter()
    {
        return new ServerEndpointExporter();
    }
}

Edit: This has been tagged as a duplicate of this question. I have tried the solution specified in the answers. The solution is to add SpringConfigurator as configurator of the @ServerEndpoint. After adding this I still do get the error mentioned in the details.

Vino :

After some research I found a way to force spring-boot to inject a component into an externally managed/instantiated class.

1) Add a generic method to your class extending ApplicationContextAware to return a bean.

@Component
public class SpringContext implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringContext.context = context;
    }

    public ApplicationContext getApplicationContext() {
        return context;
    }

    // Generic method to return a beanClass
    public static <T> T getBean(Class<T> beanClass)
    {
        return context.getBean(beanClass);
    }
}

2) Use this method to initialize the class object you want to be injected

private IntelligentResponseService responseServiceFacade = SpringContext.getBean(IntelligentResponseService.class);

So after the above changes my websocket controller would look like this

@ServerEndpoint(value = "/call-stream", configurator = SpringConfigurator.class)
public class CallStreamWebSocketController
{  
    private IntelligentResponseService responseServiceFacade = SpringContext.getBean(IntelligentResponseService.class);

    // Other methods
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=103486&siteId=1