SpringMVC conflicts with existing,non-compatible bean definition of same name and classの解決方法

7160 ワード

問題の原因


最近、プロジェクトチームの同僚が問題に遭遇しました.彼自身が担当しているモジュール、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のクラス名(全クラス名ではない)をキーとして使用します.このように,異なるパッケージの下にある2つの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";

    }



}

上の2つのコードは、異なるパッケージの下、すなわち全クラス名が異なるが、クラス名は同じである.
これにより、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に配置します.
たとえば、上記の例では、上記の2つのクラスの全クラス名が異なるにもかかわらず、@Controller注釈を使用した場合、名前は使用されません.SpringMVCがControllerをスキャンすると、デフォルトでbillSaveControllerとして解析されます.そしてこのbillSaveControllerをキーとして、グローバルなmapに配置します.
すると、2つのキーがまったく同じ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";

    }



}

上の2つのControllerでは、1つに名前が付けられていることを保証すればよいが、両方とも使用することが望ましい.
これは、他の人があなたと同じクラス名のControllerを使用しないことを保証できないため、良いプログラミング方法です.

後記:


午後は同僚にやってもらったが、やはりよかった.