我知道我需要在我的servlet上下文中注册注解为@Controller
的类,以使我的webapp可用。 Usualy,我这样做:Spring根应用程序上下文和Servlet上下文混淆
@Configuration
@EnableWebMvc
@ComponentScan({"foo.bar.controller"})
public class WebConfig extends WebMvcConfigurerAdapter {
//other stuff like ViewResolvers, MessageResolvers, MessageConverters, etc.
}
我添加到我的根应用程序上下文中的所有其他配置类。下面是我的dispetcher初始化usualy样子:
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事情变得更有趣。为了让websocket工作,你必须把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);
}
}
我需要使用一些其他的服务队这个服务(它的自动装配)。现在我在僵局:
- 如果我试图创建根应用上下文中
TimeServiceWs
豆,预期它不会看到SimpMessagingTemplate
豆,并抛出NoSuchBeanDefinitionException
- 如果我试图创建
TimeServiceWs
bean里面的servlet上下文,然后我无法自动装载到任何其他服务,因为根上下文无法看到servlet上下文bean(据我所知) - 如果我将所有的配置移动到servlet上下文,所有豆成功创建,但我收到以下例外:
java.lang.IllegalStateException: No WebApplicationContext found
,无法访问我的web应用程序
我该怎么办?什么应该在根上下文中?什么应该在servlet的上下文中?你能否再请一次澄清这些背景之间的区别?
如果您需要任何额外的信息,请让我知道。
当你说“将SimpleMessagingTemplate移动到根上下文”..我真的不知道如何移动...我很抱歉...非常新的春天... –
问题是,我不能轻松移动SimpMessagingTemplate是因为Spring创建了这个bean,它依赖于其他Spring创建的bean。 我找到的解决方案是迁移到Spring Boot - 可能它在根应用程序配置中注册了WebSocketConfig,所以问题没有发生。所以问题的根源在于我在错误的上下文中注册配置。 –