弹簧根应用程序上下文和 servlet 上下文混淆
我知道我需要注册在我的servlet上下文中注释的类,以使我的Web应用程序可访问。通常,我会按以下方式进行:@Controller
@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正常工作,您必须将WebSoketConfig.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);
}
}
我需要在其他一些服务(自动连接)中使用此服务。现在我陷入了僵局:
- 如果我尝试在根应用程序上下文中创建Bean,正如预期的那样,它看不到bean并抛出
TimeServiceWs
SimpMessagingTemplate
NoSuchBeanDefinitionException
- 如果我试图在servlet上下文中创建bean,那么我无法将其自动连接到任何其他服务,因为根上下文看不到servlet上下文bean(据我所知)
TimeServiceWs
- 如果我将所有配置移动到 servlet 上下文,则所有 Bean 都已成功创建,但我得到以下异常:并且无法访问我的 webapp
java.lang.IllegalStateException: No WebApplicationContext found
我该怎么办?根上下文中应该包含哪些内容?servlet 上下文中应该包含哪些内容?你能不能再澄清一下这些背景之间的区别?
如果您需要任何其他信息,请告诉我。