실무에서 @Component로 Bean을 편리하게 만들어줘서 사용하고 있지만, 동작 원리부터 어떤 식으로 작용하는지 궁금했습니다.
일단 @Component를 쓰기 위해서는 @ComponentScan과 @Configuration을 알아야 합니다.
@Configuration는 간단하게 이야기하자면 해당 클래스는 설정파일이라고 인식시켜 주는 것입니다. Bean Object 생성 이상으로 전체 애플리케이션을 구성하는 가장 중요한 기능들을 넣을 수 있습니다.
@ComponentScan는 @ComponentScan를 적용한 해당 클래스 아래에 있는 @Component가 붙은 모든 클래스들을 Bean으로 등록할 수 있게 도와줍니다. 필요하다면 의존 Object를 찾아서 생성자를 찾아 파라미터로 넘겨주기도 합니다.
@Component를 직접 해당 클래스에 붙여서 Bean으로 등록해도 되지만, 메타에노테이션으로 만들어서 붙여서 사용할 수 있습니다. 메타에노테이션은 해당 에노테이션 위에 붙어있는 에노테이션을 뜻합니다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
public @interface WebComponent {
// bean 오브젝트가 어떤 의미인지 커스텀, 명시해줄 때 사용 Ex) 웹 계층인지, controller, service 등등...
// 메타어노테이션
}
@WebComponent를 하나 정의해봤습니다. 해당 어노테이션의 생명주기를 설정하는 @Retention은 RUNTIME 시점으로 해주고, @Target은 지정된 타깃 위치만 해당할 수 있도록 설정해 줍니다. ElementType.TYPE 설정을 통해 Class나 interface 같은 타입에만 적용해 줄 수 있도록 해줍니다. 마지막으로 @Component로 컴포넌트로 인식할 수 있도록 작성해 주면 메타어노테이션을 생성할 수 있습니다. 해당 어노테이션을 사용하는 곳에서는
@WebComponent
public class WebController {
일반적인 어노테이션처럼 사용해주면 됩니다. 이러한 원리로 우리가 흔히 사용하고 있는 @Controller, @RestController, @Service도 이러한 원리로 동작하고 있습니다.
각 각의 구현체를 확인해보겠습니다.
@Controller를 확인해 보면 Bean의 생명주기 설정, 타입설정, 문서설정을 해주고 @Component를 통해 Bean으로 등록할 수 있게 됩니다.
@Service도 마찬가지로 동일하게 설정해 주는 것을 볼 수 있습니다.
여기서 저는 사실 @Service든 @Controller든 Bean을 등록해 주는 똑같은 코드를 왜 분리했을까? 생각했습니다. 고민한 결과
@Component로 Bean 생성을 해줄 수 있지만, 각 각의 Layer를 구분하여 더 좋은 아키텍처를 구성할 수 있다고 생각했습니다. 하지만 사용하지 않아도 @Component를 구성하는 올바른 구조, 설계만 있다면 사용하지 않아도 충분히 좋은 아키텍처를 만들 수 있다고 생각합니다.
@RestController를 살펴보면, @Controller 메타어노테이션을 가지고 있습니다. 메타어노테이션은 메타어노테이션 안에 메타어노테이션... 쭉 계층형으로 가져갈 수 있습니다. 결국 그 안에는 @Component가 붙어있을 것입니다.
그러면 굳이 @RestController를 왜 만들었을까?
위에 사진을 살펴보면, @ResponseBody 어노테이션 하나가 더 붙은 것을 볼 수 있습니다. 그 이유는 API 역할의 Controller 메서드를 만들 경우 ResponseBody가 Controller에 붙어있는 것으로 DispatcherServlet이 인식하게 됩니다. Controller를 조금 더 확장한 RestController를 사용할 수 있게 되는 것입니다. 장점으로는 @RestController를 사용하게 된다면 Class 레벨의 @RequestMapping을 작성을 안 해줘도 DispatcherServlet이 해당 클래스 안에 Mapping 정보가 있다고 가정하여 찾아줍니다. Method 레벨에 Mapping을 작성해줘도 됩니다.
'혼자 공부하는 것들 > Spring' 카테고리의 다른 글
서버가 죽었다!.... 502....(100 % of root file system is in use. 0 MB free.) (0) | 2023.05.06 |
---|---|
회사에서 Spring batch 짜면서 삽질한거 정리 (1) | 2023.04.05 |
spring-data-envers로 데이터 변경 이력(히스토리)을 관리해보자! (0) | 2022.09.04 |
[Spring] @RequestBody는 객체로 받자! (0) | 2022.05.30 |
Reflection(리플렉션) 활용 (0) | 2022.05.22 |
댓글