应用程序启动时,同一个 VM 中已存在另一个具有相同名称“”的 CacheManager

Another CacheManager with same name '' already exists in the same VM while application starts

net.sf.ehcache.CacheException: Another CacheManager with same name 'fernowebapp' already exists in the same VM. Please provide unique names for each CacheManage
r in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.

这是web.xml

 <servlet>
    <servlet-name>ferno</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
<!--         <load-on-startup>1</load-on-startup> -->
</servlet>
<servlet-mapping>
    <servlet-name>ferno</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/ferno-servlet.xml</param-value>
</context-param>
<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.vuelogix.collygo.context.FernoApplicationContextInitializer</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

当我检查日志时,我发现应用程序上下文被初始化了两次。我刚刚通过禁用调度程序 servlet 启动时的负载来验证它。当我禁用调度程序 servlet 时,我发现异常不会在启动时出现。但它发生在我第一次尝试点击任何控制器 class 时。

我在 Why does Spring MVC need at least two contexts? , Spring - application Initialized twice?

中发现了几个类似的问题

在下面的link中提到,对于Ehcache 2.5 及更高版本,不允许在同一个JVM 中存在多个同名的CacheManager。创建非单例 CacheManager 的 CacheManager() 构造函数可能违反此规则。

Another unnamed CacheManager already exists in the same VM (ehCache 2.5)

如果要再次加载应用程序上下文以初始化调度程序 servlet,初始化 class CacheManager 之类的最佳方法是什么?

我相信如果我为调度程序 servlet 添加初始化参数,它会起作用。评论中提到。就我而言,我没有用于调度程序 servlet 的单独应用程序上下文,因此我相信它在我的应用程序上下文中工作正常。 更新: 因此,当我真的需要为我的调度程序 servlet 提供单独的应用程序上下文时,最佳做法是从第二个上下文中删除缓存声明(在本例中)并在根配置上进行这些配置?如果我错了请纠正我

您几乎找到了 Why does Spring MVC need at least two contexts? 个问题的答案。

当您使用 Spring MVC 时,您拥有根上下文和使用根作为其父级的调度程序 servlet 上下文。

但是这里有:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/ferno-servlet.xml</param-value>
</context-param>

您声明应该从 /WEB-INF/ferno-servlet.xml 加载根上下文,并且当您将 servlet 命名为 ferno 时,DispatcherServlet 上下文是从同一个文件加载的。然后你在每个上下文中创建每个 bean 两次 - 这至少是危险的......

所以你必须声明2个上下文并且:

  • 要么
    • 放入根一:所有与调度程序 servlet 无关的内容:模型、持久性 bean、过滤器等
    • 放入调度程序 servlet 一:控制器、视图、拦截器等
  • 或者将所有内容都放在根上下文中并将另一个留空。这是可行的,因为根上下文是第一个调度程序 servlet 的父级,因此 Spring MVC 在第二个中找不到的根上下文 bean 中查找。

永远不要为根应用程序上下文使用 xxx-servlet.xml 这样的名称来避免此类问题。