我知道我需要在servlet上下文中注册标注有@Controller
的类才能让我的Web应用程序可以访问。通常,我会按照以下方式进行操作:
@Configuration
@EnableWebMvc
@ComponentScan({"foo.bar.controller"})
public class WebConfig extends WebMvcConfigurerAdapter {
//other stuff like ViewResolvers, MessageResolvers, MessageConverters, etc.
}
我将所有其他的配置类都加入了我的根应用程序上下文中。以下是我的调度程序初始化程序通常的外观:
public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class, ServiceConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
但是当我开始使用WebSockets时,事情变得更有趣了。要使WebSockets工作,您必须将WebSocketConfig.class放入servlet上下文中。以下是我的WebSocketConfig示例:
@Configuration
@EnableScheduling
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat").withSockJS();
}
@Override
public void configureClientInboundChannel(ChannelRegistration channelRegistration) {
channelRegistration.taskExecutor().corePoolSize(4).maxPoolSize(8);
}
@Override
public void configureClientOutboundChannel(ChannelRegistration channelRegistration) {
channelRegistration.taskExecutor().corePoolSize(4).maxPoolSize(8);
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue", "/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
同时,我创建了一个发送消息到主题的服务:
@Service
public class TimeServiceWsImpl implements TimeServiceWs {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@Override
public void sentCurrentTime() {
long currentTime = System.currentTimeMillis();
String destination = "/topic/chatty";
logger.info("sending current time to websocket /topic/time : " + currentTime);
this.messagingTemplate.convertAndSend(destination, currentTime);
}
}
我需要在其他服务中使用此服务(自动装配它)。但现在我陷入了僵局:
- 如果我尝试在根应用程序上下文内创建
TimeServiceWs
bean,那么如预期所料,它将无法看到SimpMessagingTemplate
bean,并抛出NoSuchBeanDefinitionException
- 如果我尝试在 servlet 上下文中创建
TimeServiceWs
bean,则无法将其自动装配到任何其他服务中,因为根上下文无法看到 servlet 上下文中的 bean(据我所知) - 如果我将所有配置移动到 servlet 上下文中,则所有 bean 都将成功创建,但我会得到以下异常:
java.lang.IllegalStateException: No WebApplicationContext found
,并且无法访问我的 web 应用程序
如果您需要任何其他信息,请告诉我。