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 rzutyNoSuchBeanDefinitionExceptionJeś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 internetowej

Co 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ć.

questionAnswers(2)

yourAnswerToTheQuestion