kas*_*tti 13 java spring spring-mvc
我有一个耳包,其中包含一个带有常见对象的jar和两个war webapps,我想使用普通的jar.我已经将配置设置为通过ContextLoaderListener和webapp上下文分别为DispatcherServlet使用应用程序范围的上下文.
我的演示应用程序的设置大致如下
common.jar
包含applicationContext.xml和beanRefContext.xml,它们应该是应用程序(耳朵)广泛的上下文.文件如下所示.共享命名空间是共享bean所在的位置.的applicationContext
<beans>
<!-- namespace etc declarations omitted -->
<context:annotation-config />
<context:component-scan base-package="study.spring.multicontext.shared" />
</beans>
Run Code Online (Sandbox Code Playgroud)
beanRefContext.xml
<beans>
<!-- namespace etc declarations omitted -->
<bean id="sharedContext" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>classpath*:applicationContext.xml</value>
</list>
</constructor-arg>
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
webapp1
并将webapp2
Spring MVC应用程序打包为具有web.xml文件的单独战争,如下所示
<web-app>
<context-param>
<param-name>parentContextKey</param-name>
<param-value>sharedContext</param-value>
</context-param>
<context-param>
<param-name>locatorFactorySelector</param-name>
<param-value>classpath:beanRefContext.xml</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dos</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dos-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dos</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)
和xx-servlet.xml类似于webapp特定的上下文.web命名空间是控制器所在的位置.
<beans>
<!-- namespace etc declarations omitted -->
<context:component-scan base-package="study.spring.multicontext.web"/>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
在Controller类中,共享bean以正常方式@Autowired
@Autowired
MySharedBean mySharedBean
Run Code Online (Sandbox Code Playgroud)耳包含有战争和罐子,结构就像
ear
|
|--common.jar
| |--META-INF
| |--applicationContext.xml
| |--beanRefContext.xml
|
|--webapp1.war
| |--WEB-INF
| |--xx-servlet.xml
| |--web.xml
|
|--webapp2.war
| |--WEB-INF
| |--xx-servlet.xml
| |--web.xml
Run Code Online (Sandbox Code Playgroud)问题是bean仍然会有两个实例.每个控制器/ webapp一个,因为每个战争中只有一个控制器.我试图改变配置,但无论我做什么,我要么得到零实例,要么得到两个实例.
我从内存转储中检查了带有Eclipse MAT的引用,实际上有4个实例,但我猜这两个是Spring内部使用的.无论如何,从那里可以清楚地看到每个控制器都有它自己的实例.
我已经阅读了很多博客文章,论坛等,他们说这应该就这么简单.有人建议JNDI,但正如我所理解的,如果没有它,这应该是可能的.
并且不可能将战争结合起来并将罐子捆绑在里面.因为它可能适用于这个演示应用程序,我正在使用的真实案例不允许这样做.
对此事的任何帮助都非常感谢.提前致谢.
2007年的SpringSource示例用于Spring 2.X,它具有相同的功能,但具有不同的配置.有点过时,正在寻找基于Spring 3.X的解决方案,正如赏金说明中所述.
就应用程序上下文层次结构而言,我认为从Spring 2.x到3.x没有任何变化.
从我所知道的,你的配置问题是你正在加载applicationContext.xml
- 加载到的那个sharedContext
,也被每个webapp加载,因为它在中提到的事实context-param
contextConfigLocation
.
由于同一文件被加载两次,一次在父上下文中,一次在Web应用程序的根上下文中,所以有副本和子上下文,即.webapp,使用它创建的那些,而不是父项中存在的那些.
更改您的配置,这样您就不会重新加载相同的bean xml两次,它应该可以正常工作.您可以使用parentContextKey
,contextConfigLocation
只是不加载相同的文件.
更新:除了上述内容之外,您还需要检查共享jar是否对战争可见(在允许共享同一实例时可见).我尝试从博客中运行该示例,当我将其部署为Java EE6应用程序时,它对我不起作用,这是因为战争中的耳罐可见性规则从Java EE5更改为EE6.当我在Glass Fish的兼容模式下运行样本时,一切都按预期工作.
因此,请检查您的EAR/WAR以查看正在运行的servlet规范,并确保您的服务器正在相应地部署应用程序.
如果必须升级到Java EE 6,请确保遵循最新的可见性规则http://docs.oracle.com/cd/E19226-01/820-7688/gjjdt/index.html.检查MANIFEST
战争文件,确保它们具有Class-Path
配置中明确提到的所有耳罩.
希望这可以帮助.
归档时间: |
|
查看次数: |
13704 次 |
最近记录: |