Parameter 0 of constructor in {0} required a bean of type {1} that could not be found.
문제 발발
공부를 하거나 일을 하다보면 이런 에러들이 나온다. 개발자라면 이 에러를 긁어다가 구글에 검색해 볼 것이다. 나 또한 그랬고, 처음 접해보는 코틀린에 헤메다가 답을 찾았던 경험이다.
Spring Framework로 프로젝트를 구성하는 도중 발생한 이슈다.
다행히 책을 보면서 공부하다가 발생한 일이라 쉽게 풀린 경우다. 업무 중에 이런 일이 발생하면 사실 찾기가 힘들다. 간단한 이유다. 내 상황과 전부 다른 상황에서 비슷한 에러가 나오기 때문이다.
그렇다면 다양한 경우를 적어두면 많은 개발자들이 좀 더 쉽게 에러를 고치지 않을까?
그렇게 해서 적게 되었다.
에러는 제목과 같았고, 내 코드다.
@Controller
class FirstController (var exampleService: ExampleService){
@Autowired
lateinit var service: ServiceInterface
@RequestMapping(value = "/user/{name}", method = arrayOf(RequestMethod.GET))
@ResponseBody
fun hello(@PathVariable name: String) = service.getHello(name)
}
일부분만 가져왔다. 여기서 에러가 났었다.
에러가 발생한 부분은 FirstController에 Parameter 부분을 지우지 않아서 발생했다. 이유는 아래의 코드를 보면 알 수 있다.
@SpringBootApplication
class CentbinApplication {
@Bean
@ConditionalOnExpression("#{'\${service.message.type}'=='simple'}")
fun exampleService() : ServiceInterface = ExampleService()
@Bean
@ConditionalOnExpression("#{'\${service.message.type}'=='advance'}")
fun advanceService() : ServiceInterface = AdvanceService()
}
ServiceInterface에 2개의 Service를 주입했다. @Bean를 사용했고, Controller에서 설정에 따라 service를 선택할 수 있도록 코드가 작성되었다.
그런데 위에 보면 Parameter로 ExampleService가 있다. 왜 에러가 났을까?
Controller에서 Parameter로 가져오기 위해서는 Service 등록이 필요하다.
class ExampleService : ServiceInterface {
@Value(value = "\${service.message.text}")
private lateinit var text: String
override fun getHello(name : String) = "$text $name"
}
위 코드는 ExampleService다. @Service가 없다. 그래서 에러가 났다. interface로 2개의 Service를 만들기 전에는 있었으나 @Autowired를 사용한 이후에는 필요가 없어서 삭제 했었다.
위와 비슷한 에러가 발생한다면 위 사례를 참고하여 해결하길 바란다.