Sé que hay muchas preguntas sobre este tema. He leído el documento de arranque primavera y todas las soluciones aquí. Según doc arranque primavera, @ServerEndpoint
es una anotación de Javax y @Autowired
componentes son resorte de arranque logró. Estos dos no pueden utilizarse juntos. La solución a esto sería añadir SpringConfigurator
como configurador de la ServerEndpoint
. Cuando intenté esto hago el siguiente error:
No se pudo encontrar el WebApplicationContext raíz. No se utiliza ContextLoaderListener?
No hay ningún ejemplo en el WebSocket resorte de arranque página de usar ContextLoaderListener
. ¿Cómo se puede utilizar ContextLoaderListener
para que los componentes se pueden inyectar en @ServerEndpoint
los controladores anotados?
El siguiente es mi código.
WebSocket controlador
@ServerEndpoint(value = "/call-stream", configurator = SpringConfigurator.class)
public class CallStreamWebSocketController
{
@Autowired
private IntelligentResponseService responseServiceFacade;
// Other methods
}
configuraciones WebSocket
@Configuration
public class WebSocketConfiguration
{
@Bean
public CallStreamWebSocketController callStreamWebSocketController()
{
return new CallStreamWebSocketController();
}
@Bean
public ServerEndpointExporter serverEndpointExporter()
{
return new ServerEndpointExporter();
}
}
Editar: Esta ha sido etiquetado como un duplicado de esta cuestión. He intentado la solución especificada en las respuestas. La solución es añadir SpringConfigurator
como configurador de la @ServerEndpoint
. Después de la adición de este que todavía lo hacen obtener el error mencionado en los detalles.
Después de algunas investigaciones he encontrado una forma de fuerza de resorte de arranque para inyectar un componente en una clase administrada externamente / instancia.
1) Añadir un método genérico a su clase que se extiende ApplicationContextAware
a devolver un frijol.
@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) Utilizar este método para inicializar el objeto de clase que desea ser inyectado
private IntelligentResponseService responseServiceFacade = SpringContext.getBean(IntelligentResponseService.class);
Así que después de los cambios por encima de mi controlador de WebSocket sería el siguiente
@ServerEndpoint(value = "/call-stream", configurator = SpringConfigurator.class)
public class CallStreamWebSocketController
{
private IntelligentResponseService responseServiceFacade = SpringContext.getBean(IntelligentResponseService.class);
// Other methods
}