我在Spring MVC documentation发表以下声明:
初始化
DispatcherServlet
后,Spring MVC会查找 名为[servlet-name] -servlet.xml的文件位于WEB-INF
目录中 您的Web应用程序并创建在那里定义的bean,覆盖 在全局中使用相同名称定义的任何bean的定义 范围。
请帮助我理解这句话。
由于全局范围用于基于portlet
的应用程序,那么开发人员为什么要在普通Spring MVC
应用程序中进行此类配置?
答案 0 :(得分:2)
我不认为术语“全局范围”在这里意味着全局范围bean,如单例,原型,请求,会话和全局。我相信全局范围在这里意味着bean上下文的范围。
在Spring MVC中,可以定义2个bean范围。第一个是在servlet上下文级别,我认为它是上述语句中“全局范围”的含义。第二个是在servlet级别,在servlet级别中由其他bean解析时,在此级别定义的bean将具有优先级。
servlet级别的bean将能够在servlet上下文(全局)级别解析bean,但不能反过来。
答案 1 :(得分:1)
Spring MVC提供了根据DispacthServlet配置的数量配置多个Context的选项。
例如
假设您的应用程序中有两个模块,并且url模式以module1 / *和module2 / *开头。并且您希望保留两个不同的上下文(* context.xml中的声明始终对上下文是私有的)。因此,您将创建两个dispatchServlet并提供两个不同的servletname和url模式。现在你有两个Spring上下文,它具有特定的声明,并且对其他声明不可见。但是你仍然想要声明一些应用程序范围的bean,例如persistentManager / Logger实例等等。对于这些情况,您可以将单独的配置保存为root-context.xml,并将通用声明保留在该根目录中。这里被认为是“GLOBAL SESSION”
现在这个全局会话bean范围可以是基于配置的不同范围。并且可以通过特定servlet覆盖在全局会话(根上下文)中配置的bean进行自定义。
我也喜欢这里提供的答案Understanding contexts in Spring MVC
答案 2 :(得分:1)
典型的Spring MVC应用程序将有两个上下文:根上下文和servlet上下文。
根上下文由ContextLoaderListener
加载。 ContextLoaderListener
加载ApplicationContext
并将其设置为ServletContext
中的属性。这使其可供其他Servlet
,Filter
和XxxListener
实例使用。
当调用其ApplicationContext
方法时,DispatcherServlet
加载了另一个init()
servlet上下文。由于在调用init()
的{{1}}方法后调用了Servlet
contextInitialized()
方法,因此ServletContextListener
可以访问根上下文设置为DispatcherServlet
中的属性,因此可以使用在那里声明的bean。
[...]创建那里定义的bean,覆盖any的定义 在全局范围内使用相同名称定义的bean。
bean定义例如是
ContextLoaderListener
Spring为此和所有其他<bean id="someBean" class="com.company.SomeBean">
<property name="someProp" value="some value" />
</bean>
声明(或<bean>
注释方法)创建一个BeanDefinition
对象。刷新@Bean
时,Spring会从这些bean定义生成实际实例。
文档上面引用的内容是,如果在根上下文和servlet上下文中都有ApplicationContext
或<bean>
的{{1}}声明,那么servlet上下文一将覆盖根上下文一。