我知道我需要@Controller
在servlet上下文中注册带注释的类,以使我的webapp可访问。通常,我通过以下方式进行操作:
@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[] { "/" };
}
}
但是当我开始使用WebSocket时,事情变得越来越有趣。要使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
在根应用程序上下文中创建bean,则按预期不会看到SimpMessagingTemplate
bean并抛出NoSuchBeanDefinitionException
TimeServiceWs
在servlet上下文中创建bean,则无法将其自动连接到任何其他服务,因为根上下文看不到servlet上下文bean(据我所知)java.lang.IllegalStateException: No WebApplicationContext found
并且无法访问我的Web应用程序我应该做些什么?根上下文内应该是什么?servlet上下文内部应该是什么?您能否再澄清一下这些上下文之间的区别?
如果您需要任何其他信息,请告诉我。
大多数Spring MVC应用程序都有一个包含所有服务层/ DAO层Bean的根上下文,以及该应用程序的每个Spring Dispatcher Servlet一个Servlet上下文,该Servlet上下文包含(至少)每个Servlet的控制器。
其想法是,一个应用程序可能具有多个servlet调度程序,例如一个用于URL /shopping/*
,另一个用于URL /reporting/*
,每个调度器都有自己的一组控制器。
一个servlet调度程序的控制器是相互隔离的,这意味着尽管它们也是Spring Bean,但不能相互注入。
根上下文中的服务层和DAO Bean在所有Servlet上下文中都是可见的,因此可以在任何控制器中注入服务层Bean,但不能以其他方式注入。
根上下文被称为控制器Servlet上下文的父级。
所有这一切都是要使一组豆相互隔离的机制,以确保不会产生不协调的依赖关系。
鉴于此并经历了以下问题:
如果我试图在根应用程序上下文中创建TimeServiceWs Bean,则按预期不会看到SimpMessagingTemplate Bean并抛出NoSuchBeanDefinitionException:将SimpleMessagingTemplate移到根上下文中,这是一个像DAO一样的bean,可以在应用程序中的任何地方使用,因此它应该在共享根上下文中。
如果要在servlet上下文中创建TimeServiceWs Bean,则无法将其自动连接到任何其他服务:如果要自动连接到其他服务,则将其保留在根上下文中。
-如果我将所有配置都移到servlet上下文,则所有的bean都创建成功,但是我得到java.lang.IllegalStateException:没有找到WebApplicationContext:进行相反的操作,基本上将所有bean移到根上下文,仅保留在servlet上下文中特定于应用程序那部分的bean,很多时候只有控制器。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句