nimasike
温故而知新666
2013-08-19 13:51

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条回答

  • zyn010101 zyn010101 8年前

    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);)

    点赞 评论 复制链接分享
  • zm112358 zm112358 8年前

    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.第三个问题,应该已经解释明白了。
    至于楼主出现的错误,不妨楼主贴出来异常,大家共同研究下。

    点赞 8 评论 复制链接分享
  • jinandmei jinbingchuan 8年前

    你加载了配置文件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



    不要重复

    点赞 3 评论 复制链接分享
  • chen978616649 javaDocker 7年前

    个人建议,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 />
    

    点赞 评论 复制链接分享
  • weixin_42628032 victor-张 8年前

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

    点赞 评论 复制链接分享

相关推荐