Contents
ConflictingBeanDefinitionExceptionが発生した時のログ
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'editConfirmController' for bean class [com.springhack.okozukaisystem.controller.help.EditConfirmController] conflicts with existing, non-compatible bean definition of same name and class [com.springhack.okozukaisystem.controller.children.EditConfirmController]
ConflictingBeanDefinitionExceptionの原因と対策
原因 同じクラス名のコントローラーやサービスがありませんか?
SpringBootでは、@Controller @Service @Repsitory をつけたクラスは、起動時に自動でBean登録されます。
Bean登録されたクラスは適宜インスタンス化され、DIされます。
Bean登録するときに、各クラスのBeanには名前が付与されます。
名前は基本的にはクラス名の先頭を小文字にしたものが付与されます。
例えば、
・ChildrenController なら、Bean名は childrenController。
・ChildrenResiterService なら、Bean名は childrenResiterService。
という具合です。
パッケージ名は関係ありません。
そのため、同じクラス名のコントローラーやサービスクラスが存在すると、
Beanに登録するときに名前が重複してしまうので、エラーとなります。
解決策 クラスの名前を変えるか、Bean名を指定する
2つの解決策があります。
解決策1 クラスの名前が被らないように変更する。
重複しないようにいずれか又は両方のクラス名変更してください。
xxx.ResiterService と yyy.ResiterServiceが存在するなら、
XxxResiterService と YyyResiterServiceという風に。
これでSpringBootは起動できるようになります。
解決策2 クラス名はそのままで、Bean名を直接指定する。
@Controller("XxxEditController")
public class EditController {
@GetMapping
public String doGet() {
return "help/edit";
}
}
このように、アノテーションの引数にBean名を渡すことができます。
これだけでSpringBootは起動できるようになります。
Service/Repositoryのクラス名も同様にBean名を指定します。
クラスを使う際には、パッケージ名で区別が可能です。
package com.springhack.okozukaisystem.service.children;
import org.springframework.stereotype.Service;
@Service("ChildrenRegisterService")
public class RegisterService {
public void register() {
// do something!
}
}
package com.springhack.okozukaisystem.controller.children;
import com.springhack.okozukaisystem.service.children.RegisterService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/children/register")
@Controller
public class RegisterController {
private final RegisterService registerService;
public RegisterController(RegisterService registerService) {
this.registerService = registerService;
}
@GetMapping
public String doGet() {
registerService.register();
return "children/register";
}
}