zoukankan      html  css  js  c++  java
  • SpringMVC conflicts with existing, non-compatible bean definition of same name and class 的解决办法

    问题起因

    最近,项目组的里的同事遇到一个问题,他自己负责的模块,SpringMVC的Controller与其他模块的Controller 类名重名了,导致整个工程都起不来了。

    后台报的错误是这样的:

    ××Controller' for bean class [××ontroller] conflicts with existing, non-compatible bean definition of same name and class 
    

    午饭时,他一直和我抱怨这个问题,还说找不到办法。

    后面我想了一下,SpringMVC的Controller 应该是采用类似键值对(key/value)的映射方式处理的。而当中的键,默认是用cotroller的类名(非全类名)作为键。这样,如果不同包下面的两个Contoller 重名的话,就会导致SpringMVC的容器管理中的controller map中的key重复了。

    解决这个问题也比较简单。

    在@Controller 中,使用重名名就可以了

    如 下例子:

    test.controller.bill.BillSaveController
    package test.controller.bill;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * Created by liuch on 5/27/15.
     */
    @Controller
    @RequestMapping("/billsave")
    public class BillSaveController {
    
        @RequestMapping("/dosave")
        public String saveBill(){
    
            return "billsave";
        }
    
    }

    及 test.controller.bill.BillSaveController

    package test.controller.billsave;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * Created by liuch on 5/27/15.
     */
    @Controller
    @RequestMapping("/billsave_test")
    public class BillSaveController {
    
        @RequestMapping("/test")
        public String test(){
            return "test";
        }
    
    }

    上面这两个代码虽然在不同的包下面,即全类名不同,但是类名却是相同。

    这样,在Tomcat 启动的时候,后台会报错:

    SEVERE: Context initialization failed
    org.springframework.beans.factory.BeanDefinitionStoreException: 
    
    Unexpected exception parsing XML document from ServletContext resource
    [/WEB-INF/dispatcher-servlet.xml]; 
    
    nested exception is java.lang.IllegalStateException: 
    
    Annotation-specified bean name 'billSaveController' for 
    bean class [test.controller.billsave.BillSaveController] 
    conflicts with existing, non-compatible bean definition of same name 
    and class [test.controller.bill.BillSaveController]

    问题原因:

    因为如果在使用注解 @Controller 时候,如果不使用命名,而SpringMVC会默认把类名的头一个字母小写,然后放到一个map中。

    比如上面的例子,尽管上面两个类全类名不同,但是他们使用了@Controller 注解的时候,都没有使用命名。在SpringMVC在扫描Controller的时候,会把他们都默认解析为 billSaveController.然后以这个billSaveController为键(key), 放到一个全局的map中。

    这样,就会出现两个键完全一样的Controller。由于SpringMVC不使用覆盖的方式处理具有相同键的不同全类名的Controller,、扫描的时候就会包上面的错误。

    解决的办法:

    在@Controller上使用名称

    如:test.controller.bill.BillSaveController中

    package test.controller.bill;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * Created by liuch on 5/27/15.
     */
    @Controller("testbillsave")
    @RequestMapping("/billsave")
    public class BillSaveController {
    
        @RequestMapping("/dosave")
        public String saveBill(){
    
            return "billsave";
        }
    
    }
    test.controller.billsave.BillSaveController中,使用:
    package test.controller.billsave;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    /**
     * Created by liuch on 5/27/15.
     */
    @Controller("realbillsave")
    @RequestMapping("/billsave_test")
    public class BillSaveController {
    
        @RequestMapping("/test")
        public String test(){
            return "test";
        }
    
    }

    上面两个Controller中,只要保证一个有命名即可,但是最好两个都使用上。

    这是一种良好的编程方式,因为你无法保证其他人不会使用和你一样的类名的Controller。

    后记:

    下午让同事试了一下,果然可以了。

  • 相关阅读:
    Python学习-第三天代码作业
    网络原理-1
    整理操作系统
    操作系统--开发语言--重点
    操作系统
    C#数组的声明方式
    string.Format对C#字符串格式化(转)
    C#中两个Form窗口之间的传值(父->子)(子->父) (转)
    opencv MatchTemplate()模板匹配寻找最匹配部分
    摄像头,图片筛选颜色
  • 原文地址:https://www.cnblogs.com/a2211009/p/4534215.html
Copyright © 2011-2022 走看看