Wiosenny kontekst aplikacji root i zamieszanie w kontekście serwletu
Wiem, że muszę zarejestrować przypisane klasy@Controller
w moim kontekście serwletów, aby moja aplikacja internetowa była dostępna. Zwykle robię to w następujący sposób:
@Configuration
@EnableWebMvc
@ComponentScan({"foo.bar.controller"})
public class WebConfig extends WebMvcConfigurerAdapter {
//other stuff like ViewResolvers, MessageResolvers, MessageConverters, etc.
}
Wszystkie inne klasy konfiguracji dodałem do kontekstu aplikacji głównej. Oto jak zwykle wygląda mój inicjator dispetchera:
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[] { "/" };
}
}
Ale gdy zacząłem korzystać z WebSockets, sprawy stają się bardziej interesujące. Aby uzyskać dostęp do gniazd sieciowych, musisz umieścić WebSoketConfig.class w kontekście serwletu. Oto mój przykład 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");
}
}
Ponadto utworzyłem usługę, aby wysłać wiadomość na temat:
@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);
}
}
Muszę skorzystać z tej usługi w niektórych innych usługach (autowire to). A teraz jestem w impasie:
Jeśli próbuję stworzyćTimeServiceWs
bean wewnątrz kontekstu aplikacji root, zgodnie z oczekiwaniami, nie widaćSimpMessagingTemplate
fasola i rzutyNoSuchBeanDefinitionException
Jeśli próbuję stworzyćTimeServiceWs
bean wewnątrz kontekstu serwletu, wtedy nie mogę go automatycznie przywrócić do żadnej innej usługi, ponieważ kontekst roota nie widzi fasoli kontekstu serwletu (o ile wiem)Jeśli przeniosę wszystkie moje konfiguracje do kontekstu serwletu, wszystkie komponenty bean zostaną pomyślnie utworzone, ale otrzymam następujący wyjątek:java.lang.IllegalStateException: No WebApplicationContext found
i nie mogę uzyskać dostępu do mojej aplikacji internetowejCo powinienem zrobić? Co powinno znajdować się w kontekście głównym? Co powinno być w kontekście serwletu? Czy możesz jeszcze raz wyjaśnić różnicę między tymi kontekstami?
Jeśli potrzebujesz dodatkowych informacji, daj mi znać.