Spring root application context and servlet context confusion

后端 未结 2 913
一个人的身影
一个人的身影 2020-12-23 22:50

I know that I need to register classes annotated @Controller in my servlet context to make my webapp accesible. Usualy, I do it the following way:



        
相关标签:
2条回答
  • 2020-12-23 23:08

    WebSocket-related config belongs to the DispatcherServlet configuration one way or another. After all the HTTP handshake is processed by the DispatcherServlet through its handler mappings.

    You should be able to go with a single Spring context in a deployment scenario where there is only one DispatcherServlet in the web application. Consolidating the configuration into the root context makes more sense if using Spring Security for example although there was a bug with the AbstractAnnotationConfigDispatcherServletInitializer (see SPR-11357). Consolidating into the DispatcherServlet context should also be possible but you wrote that you got exceptions. Can you provide the exception details?

    It is also an option to have both root and DispatcherServlet contexts. In that case the WebSocket configuration will be in the DispatcherServlet context and it's not possible to inject the SimpMessagingTemplate into beans in the root context. That actually makes sense since there is one SimpMessagingTemplate to go with each DispatcherServlet (or some other servlet). What's needed is a web layer component, perhaps a thin wrapper around service layer beans (like TimeServiceWs the above example) that can also be injected with the SimpMessagingTemplate. This web layer component essentially serves as a bridge.

    0 讨论(0)
  • 2020-12-23 23:30

    Most Spring MVC applications have one root context containing all service layer / DAO layer beans, and one servlet context per spring dispatcher servlet of the application, which contains (at least) the controllers of each servlet.

    The idea being that is that one application might have several servlet dispatchers, for example one for URL /shopping/* and the other for URL /reporting/*, each with it's own set of controllers.

    The controllers of one servlet dispatcher are isolated from each other, meaning although they are also Spring beans, they cannot be injected in each other.

    Service layer and DAO beans in the root context are visible in all servlet contexts, so Service layer beans can be injected in any controller, but not the other way around.

    The root context is said to be the parent of the controller servlet context/contexts.

    It's all meant to be a mechanism of isolating groups of beans from each other to ensure no unmeant dependencies are possible.

    Given this and going through the questions:

    • If I'm trying to create TimeServiceWs bean inside root application context, as expected it doesn't see SimpMessagingTemplate bean and throws NoSuchBeanDefinitionException: Move the SimpleMessagingTemplate to the root context, it's a bean like a DAO that can be useful anywhere in the application so it should be in the shared root context.

    • If I'm trying to create TimeServiceWs bean inside servlet context, then I'm unable to autowire it to any another service: If it's meant to be autowired to other services, leave it in the root context then.

      - If I move all my configurations to servlet context, all beans are successfully created, but I get java.lang.IllegalStateException: No WebApplicationContext found: Do the opposite, move basically all beans to the root context, and leave on the servlet context only the beans that are specific of that part of the application, many times only the controllers.

    0 讨论(0)
提交回复
热议问题