1. @ModelAttribute
- 요청 파라미터를 특정 객체에 바인딩 할 때 사용된다.
- 주로 DTO나 데이터 클래스를 받아서 요청 데이터를 객체로 변환하는데 사용한다.
DTO를 매개변수로 받는 예시 ▼
//--------------------Controller----------------------------
@GetMapping("/user")
fun getUser(@ModelAttribute request: UserRequest): String {
return "Hello, ${request.name}"
}
//----------------------------------------------------------
//-------------------DTO class------------------------------
data class UserRequest(val name: String, val age: Int)
//----------------------------------------------------------
GET /user?name=John&age=25 요청이 오면 `UserRequest(name="John", age=25)` 객체가 생성된다.
2. 인터페이스를 @ModelAttribute로 받을 수 있는가?
- 일반적으로 인터페이스는 인스턴스화 할 수 없으므로 직접 바인딩 되지 않는다.
- 하지만 스프링이 자동으로 빈을 주입하는 방식을 이용하면 가능할 수 있다.
2-1. 빈으로 등록된 구현체가 있는 경우
인터페이스가 빈으로 등록된 구현체가 존재하면 스프링이 @ModelAttribute를 사용할 때 자동으로 주입할 수도 있다.
interface NameService{
fun getName(): String
}
@Service // NameService 인터페이스를 상속 받으면서 @Service 어노테이션을 사용하여 빈으로 등록하는 모습
class NameServiceImpl : NameService { // Spring이 ~~Impl 빈을 찾아서 자동으로 등록할 가능성
override fun getName() = "Spring Boot"
}
하지만 일반적으로 @ModelAttribute는 DTO 객체를 바인딩할 때 사용하고, 인터페이스 주입을 위한 방법으로는 적절하지 않다.
2-2. 스프링이 직접 바인딩 할 수 있는 경우 (커스텀 바인더를 사용한다)
요청 파라미터에서 NameService의 구현체를 생성하는 커스텀 바인더를 등록하면 가능하다. 하지만 이 방법은 일반적이지 않다.
3. 보통 빈을 주입하는 건 @Autowired나 생성자 주입을 권장한다
@RestController
class NameController(private val nameService: NameService) {
@GetMapping("/check")
suspend fun checkName(): String {
return nameService.getName()
}
}
이 방법대로라면 Spring이 NameServiceImpl을 자동으로 주입해준다.
@ModelAttribute 없이도 빈을 컨트롤러에 주입할 수 있다.
4. ModelAttribute의 동작과정
'【 개발 이야기 】' 카테고리의 다른 글
14자, 20자 날짜 포맷 (1) | 2025.03.31 |
---|---|
[Intellij] 외부 라이브러리 직접 추가하기 (2) | 2025.03.28 |
Throwable & Exception (0) | 2025.03.26 |
NotBlank, NotNull, NotEmpty 차이 (0) | 2025.03.21 |
직렬화 (0) | 2025.03.21 |