我正在尝试理解Spring MVC中应用程序上下文的概念。为了检查它,我创建了一个包含两个应用程序上下文Test-application-context1.xml
和Test-application-context2.xml
以及一个Web应用程序上下文Test-dispatcher-servlet.xml
的应用程序。在所有这些上下文中,我初始化了一个带有两个字段的简单java bean:
1)在Test-application-context1.xml
:
<bean id="testObject" class="test.TestObject">
<property name="fName" value="FirstName Context1"/>
<property name="lName" value="LastName Context1"/>
</bean>
2)在Test-application-context2.xml
:
<bean id="testObject" class="test.TestObject">
<property name="fName" value="FirstName Context2"/>
<property name="lName" value="LastName Context2"/>
</bean>
3)在Test-dispatcher-servlet.xml
::
<bean id="testObject" class="test.TestObject">
<property name="fName" value="FirstName WebContext"/>
<property name="lName" value="LastName WebContext"/>
</bean>
我还在web.xml
文件中提供了一个正确的配置,以便在服务器启动时初始化所有这些上下文:
<servlet>
<servlet-name>dispatcherTest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/Test-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherTest</servlet-name>
<url-pattern>/Test/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/Test-application-context1.xml /WEB-INF/Test-application-context2.xml</param-value>
</context-param>
现在我想在我的一个控制器类中注入这些应用程序/ Web应用程序上下文。我不确定如何正确地为多个上下文执行此操作。我知道当我有一个上下文时,我可以使我的类实现ApplicationContextAware
所以我尝试了这样:
@Controller
public class TestController implements ApplicationContextAware{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@RequestMapping(value = "/Test")
public void Test(HttpServletRequest request) {
TestObject testObject = applicationContext.getBean("testObject", TestObject.class);
System.out.println("fName="+testObject.getfName()+"; lName="+testObject.getlName());
}
}
在上面的示例中,我始终从testObject
获取Test-dispatcher-servlet.xml
的值,因此,此处注入的applicationContext
似乎表示Web应用程序上下文,但如果我说重命名{{ 1}}到{Test-dispatcher-servlet.xml'中的testObject
并运行相同的代码,我将从testObject1
获取值,所以这里是我的问题。
1)当我们创建具有多个上下文的类实现Test-application-context2.xml
时,哪个上下文将被注入该类?是一个正在注入的上下文,还是以某种方式组合所有上下文并将它们作为一个applicationContext对象注入(这可以解释为什么我在其中一个上下文中更改bean的名称时从不同的上下文中获取值) ?
2)将多个应用程序上下文注入类中的正确方法是什么?
我知道上面的例子不是一个典型的场景,可能是一个糟糕的设计模式,但我只是想了解整个事情的运作方式。
答案 0 :(得分:1)
回答你的第二个问题,
使用 @ImportResource ,如下所示。
来自docs,
与@Import一样,此注释提供类似于的功能 Spring XML中的元素。它通常在设计时使用 @Configuration classes
@Configuration
@ImportResource( { "Test-application-context1.xml", "Test-application-context2.xml" } )
public class ConfigClass { }
这会将所有应用程序上下文中的所有 bean加载到类ConfigClass中。
<强>更新强>
因此,导入后将存在仅存在一个应用程序上下文。
您可以使用@Autowired
导入后,您的示例将抛出NoUniqueBeanDefinitionException,因为您在中有超过1个带有相同名称(testObject)的bean相同的应用程序上下文。