【问题标题】:Java Spring-boot - How to use @Autowired with @ServerEndpoint?Java Spring-boot - 如何将@Autowired 与@ServerEndpoint 一起使用?
【发布时间】:2018-10-11 11:57:02
【问题描述】:

我知道关于这个话题有很多问题。我已经阅读了 spring boot doc 和这里的所有解决方案。根据 spring boot doc,@ServerEndpoint 是 Javax 注释,@Autowired 组件由 spring-boot 管理。这两个不能一起使用。对此的解决方案是将SpringConfigurator 添加为ServerEndpoint 的配置器。当我尝试这样做时,我确实收到以下错误:

未能找到根 WebApplicationContext。没有使用 ContextLoaderListener 吗?

spring-boot websocketpage中没有使用ContextLoaderListener的例子。如何使用ContextLoaderListener,以便将组件注入到@ServerEndpoint注解的控制器中?

以下是我的代码。

Websocket 控制器

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

    // Other methods
}

Websocket 配置

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

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

编辑: 这已被标记为 this 问题的副本。我已经尝试了答案中指定的解决方案。解决方案是将SpringConfigurator 添加为@ServerEndpoint 的配置器。添加后,我仍然会收到详细信息中提到的错误。

【问题讨论】:

  • 我已经提到了这个问题。它说(就像 Spring Boot 文档一样)将 SpringConfigurator 添加为 @ServerEndpoint 配置器。正如我在问题中明确表示的那样,这是行不通的。
  • 你提到的spring-websocket依赖添加到classpath了吗?
  • 我使用的是 spring-boot 而不是 spring。所以我将org.springframework.boot:spring-boot-starter-websocket 添加到我的类路径中。

标签: java spring-boot autowired java-websocket


【解决方案1】:

经过一番研究,我找到了一种强制 spring-boot 将组件注入外部管理/实例化类的方法。

1) 向您的类添加一个泛型方法,扩展 ApplicationContextAware 以返回一个 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) 使用该方法初始化你要注入的类对象

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

所以在上述更改之后,我的 websocket 控制器将如下所示

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

    // Other methods
}

【讨论】:

  • 这是唯一有效的解决方案。 spring boot 依赖注入和JSR356注解存在一些不兼容问题。
猜你喜欢
  • 2023-03-29
  • 2010-10-30
  • 2013-11-06
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
  • 2015-06-17
  • 2020-11-02
相关资源
最近更新 更多