Spring3.2MVC ContextLoaderListener DispatcherServlet 加载冲突

使用的是Spring3MVC_M2 版本
之前在Web.xml中配置如下
[code="xml"]

SpringMVC_Servlet
org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

/WEB-INF/spring-app.xml,
/WEB-INF/spring-mybatis.xml,
/WEB-INF/spring-aop.xml,
/WEB-INF/spring-ehcache.xml


1


SpringMVC_Servlet
*.do

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
    /WEB-INF/spring-app.xml,
    /WEB-INF/spring-mybatis.xml,
    /WEB-INF/spring-aop.xml,
    /WEB-INF/spring-ehcache.xml
</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

[/code]

[size=x-large]程序运行没问题,然后我在项目当中与Ehcache集成,导入Ehcache的jar包,然后增加配置如下[/size]
[code="xml"] <!-- 开启缓存对注解的支持 -->

<!-- 配置Ehcache缓存管理器,读取配置文件 -->
<bean id="ehCacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>

<!-- 配置缓存管理器,获取cache -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" >
    <property name="cacheManager" ref="ehCacheManagerFactoryBean" />
</bean>[/code]

[size=x-large]然后再启动就报错了
Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
[color=red]意思是说有重复的ID,因为以前配置过 所以我觉得肯定不是配置的原因,后来发现有一个地方不一样,那就是WEB.XML当中配置了ContextLoaderListener!!!我把它注释上启动就不报错了。
所以问题就来了。
1:为什么以前配置DispatcherServlet与ContextLoaderListener并不冲突,但是加上Eheache以后就说ID有重复。
2:我需要在程序当中得到Bean,所以我配置ContextLoaderListener。然后通过ServletContext拿到WebApplicationContext 最终得到Bean。如果我不配置ContextLoaderListener如何在Controller中得到Bean.
3: 请教一下 如果配置了DispatcherServlet 它不就会加载配置文件然后初始化Bean了吗 那还配置ContextLoaderListener有啥用,二者有什么区别。
[/color]
[/size]

[color=green][size=x-large]以上3点是我不解的地方 谢谢[/size][/color]

5个回答

springmvc和spring的ContextLoaderListener各自初始化一个ioc容器,ContextLoaderListener初始化的容器放入了ServletContext中,我们通常用的就是这个容器,用springmvc的话,所有的sping配置文件都是被加载两次的,springmvc在DispatcherServlet中初始化出来的容器相当于struts的ioc容器,主要用来做url映射用的。你所描述的原因是因为:ehcache再2.5版本以后CacheManager使用了Singleton,这样在创建多个CacheManager时就会产生上述错误。你有两种选择来解决这个问题:1.换个低版本的ehcache;2.不要再spring文件中配置CacheManager这个bean,你在自定义servlet或者filter或者listener(web.xml中listener一定要放在ContextLoaderListener的后面)中从servletContext中获取webApplicationContext,手动往里面加入cacheManager,(ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);)

nimasike
温故而知新666 谢谢你的回答。
大约 7 年之前 回复

1.楼主应该搞清楚SpringMVC和Spring之间的关系,虽然存在于一个开源框架内,但是两者其实完全的两种东西,一个是MCV框架,另一个是IOC容器,那么从这两点出发来解释DispatcherServlet与ContextLoaderListener就好解释了,ContextLoaderListener是应用上下文监听器,它主要的职能是为spring服务的初始化,依赖注入配置文件中的Bean包括
AOP,简单来说应用中如果使用springIOC,AOP部分 那就少补了它,他与springMVC的关系仅仅就是SpringMVC需要初始化的Bean必须由它来初始化。那么DispatcherServlet归根结底是一个servlet,楼主应该了解servlet到底是什么吧,DispatcherServlet就好比一个分配器,他前置分配模式或叫做前置分发模式,将web或者是ajax请求分配给不同的controller进行处理,那么两者之间的关系就弄清楚了。本身并不冲突。
2.如果没有ContextLoaderListener 那么也可以拿到bean,spring中有很多BeanFactory,用过spring的人都知道怎么用,不多说,但是有个问题就是你在controller中使用beanFactory的时候,controller怎样实例化呢?这应该是楼主思考的问题。
3.第三个问题,应该已经解释明白了。
至于楼主出现的错误,不妨楼主贴出来异常,大家共同研究下。

nimasike
温故而知新666 谢谢你的回答,异常信息关键的地方我已经贴出来了【Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following: 】 就是说Ehcache被加载了2此 ID重复了。我自己又研究了一下 发现确实是加载了2次 通过日志也看到了。 确实是因为Ehcache2.6以后用了单利模式 所以冲突了,是Ehcache被初始化了2此 报错了!! 并不是Spring的问题。 以前我没搞懂 ContextLoaderListener 加载bean 与DispatcherServlet加载bean的原理。现在懂了一些。 非常感谢你的回答,但是【zyn010101 】这个人的回答 相对贴切 而且时间也早 所以分就给他了。但是非常感谢你的回答。谢谢
大约 7 年之前 回复

你加载了配置文件2次



contextConfigLocation



/WEB-INF/spring-app.xml,

/WEB-INF/spring-mybatis.xml,

/WEB-INF/spring-aop.xml,

/WEB-INF/spring-ehcache.xml



</context-param
还有一次为

org.springframework.web.servlet.DispatcherServlet



contextConfigLocation



/WEB-INF/spring-app.xml,

/WEB-INF/spring-mybatis.xml,

/WEB-INF/spring-aop.xml,

/WEB-INF/spring-ehcache.xml





1



不要重复

nimasike
温故而知新666 谢谢你的回答。我也知道是配置重复了,但是我的问题是为什么重复了会报错? 答案也已经找到了 是因为ehcache采用了单例
大约 7 年之前 回复
jinandmei
jinbingchuan 不是我没回答到点子上,我只是提醒你一下错误在哪里没有细说,只要把上面问题解决就不会报错了
大约 7 年之前 回复
nimasike
温故而知新666 谢谢你的回答,不会没回答到点子上。我的问题是之前也加载了两次不报错,但是加上Ehcache就报错了 [zyn010101]这位兄弟回答的应该是正确的,回头我在琢磨琢磨。谢谢你的回答
大约 7 年之前 回复

补充一下前面两位的回答,ContextLoaderListener初始化了一个容器,而DispatcherServlet初始的容器是ContextLoaderListener的[b]子容器[/b];所以设计上你应该把web层的context文件给DispatcherServlet,后面所有层次的配置都给ContextLoaderListener,两个容器间不需要重复的配置文件。

个人建议,spring mvc的servlet紧加载spring-mvc.xml的配置文件。
详情如下:
<?xml version="1.0" encoding="UTF-8"?>
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<context:annotation-config />
<!-- 使用 annotation 自动注册Controller bean,并检查@Controller注解已被注入 -->
<context:component-scan base-package="com.platform" use-default-filters="false"  >
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
</context:component-scan>


<mvc:annotation-driven />

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐