Spring MVC:共享内容
我有一个耳包,其中包含一个带有常见对象的jar和两个war webapps,我想使用常见的jar。 我已经将配置设置为通过ContextLoaderListener和webapp上下文分别为DispatcherServlet使用应用程序范围的上下文。
我的演示应用程序的设置大致如下
-
common.jar
包含applicationContext.xml和beanRefContext.xml ,它们应该是应用程序(耳朵)广泛的上下文。 文件如下所示。 共享命名空间是共享bean所在的位置。
的applicationContext
beanRefContext.xml
classpath*:applicationContext.xml
-
webapp1
和webapp2
是Spring MVC应用程序打包为单独的战争, web.xml文件如下所示parentContextKey sharedContext locatorFactorySelector classpath:beanRefContext.xml contextConfigLocation classpath*:applicationContext.xml org.springframework.web.context.ContextLoaderListener dos org.springframework.web.servlet.DispatcherServlet contextConfigLocation /WEB-INF/dos-servlet.xml 1 dos /
和xx-servlet.xml类似,适用于webapp特定的上下文。 web命名空间是控制器所在的位置。
-
在Controller类中,共享bean以正常方式@Autowired
@Autowired MySharedBean mySharedBean
-
耳包含有战争和jar子,结构就像
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
问题是仍然会有两个bean实例。 每个控制器/ webapp一个,因为每个战争中只有一个控制器。 我试图改变配置,但不管我做什么,我要么得到零个实例,要么得到两个实例。
我从内存转储中检查了带有Eclipse MAT的引用,实际上有4个实例,但我猜这两个是Spring内部使用的。 无论如何,从那里可以清楚地看到每个控制器都有它自己的实例。
我读过很多博客文章,论坛等,他们说这应该就这么简单。 有人建议JNDI,但正如我所理解的,如果没有它,这应该是可能的。
并且不可能将战争结合起来并将jar子捆绑在里面。 因为它可能适用于这个演示应用程序,我正在使用的真实案例不允许这样做。
对此事的任何帮助都非常感谢。 提前致谢。
Spring.Source示例来自2007年的Spring 2.X,它使用不同的配置。 有点过时,正在寻找基于Spring 3.X的解决方案,正如赏金说明中所述。
就应用程序上下文层次结构而言,我认为从Spring 2.x到3.x没有任何变化。
据我所知,您的配置问题是您正在加载applicationContext.xml
– 加载到sharedContext
,也是由每个webapp加载的,因为它在context-param
提到的事实 – context-param
contextConfigLocation
。
由于同一文件被加载两次,一次在父上下文中,一次在Web应用程序的根上下文中,所以有副本和子上下文,即。 webapp使用它创建的那些,而不是父级中存在的那些。
更改您的配置,这样您就不会重新加载相同的bean xml两次,它应该可以正常工作。 您可以使用parentContextKey
和contextConfigLocation
,只是不加载相同的文件。
更新:除了上述内容之外,您还需要检查共享jar是否对战争可见(在允许共享相同实例时可见)。 我尝试从博客中运行该示例,当我将其部署为Java EE6应用程序时,它对我不起作用,这是因为战争中的ear jar可见性规则从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
配置中明确提到的所有耳罩。
希望这可以帮助。
我解决了。
问题在于课堂加载,因为我在评论中怀疑@ Akshay的回答。
Maven在每个war包中都包含了spring libs,因此它们被多次加载。 要解决这个问题,需要产生一场瘦弱的战争 。
我假设Akshay关于他从web.xml中的context-params中删除contextConfigLocation
答案的注释也是关键角色。
我们遇到了类似的问题。 检查我们为实验创建的这个简单的maven示例(带有2个WEB模块的EAR和共享的父春季上下文服务模块): 战争之间的共享弹簧上下文的EAR