
면접에서 대답하지 못했다.
이 질문을 대답하지 못한 것에 생각했는데, 개발할때 생각없이 사용하는 것만 신경써서 그런게 아닐까라는 고민을 했다..
내 방식에 대해 반성을 많이 하는 계기가 되었다.
스프링의 어노테이션은 그 자체로는 아무 동작을 하지 않는다.
어노테이션은 단지 "메타데이터"일 뿐이고, 스프링이 그 정보를 읽어서 동작을 만들어내는 구조이다.
1. 스프링이 실행되면 클래스 스캔
2. 어노테이션 정보를 보고 빈 생성
3. @Autowired 같은 주입 어노테이션 읽고 의존성 주입
4. 일부 어노테이션은 스프링이 '프록시 객체'를 대신 만들어서 기능 부여
5. @GetMapping 같은 것들은 URL과 메서드 연결
프로젝트 내 파일들을 찾으며, @Service, @Repository, @Controller 같은 어노테이션 탐색
@Service
public class OrderService() {}
스프링 : "이 클래스는 서비스구나, 빈으로 등록해야지"
스프링은 위에 붙어있는 어노테이션을 기준으로 클래스를 스프링 빈으로 등록
@Service -> 서비스 빈@Controller -> 컨트롤러 빈@Repository -> 레포지토리 빈빈은 스프링이 대신 만들어서 관리해주는 객체
@Autowired
private OrderService orderService;
스프링 : "이 필드에 OrderService를 넣어줘야겠네"
-> 실제로 객체를 찾아서 필드에 넣어줌
@Transactional
public void order() { ... }
이 어노테이션은 :
이 기능을 스프링이 어떻게 넣느냐?
-> 원본 객체를 감싸는 '프록시'를 만들어서 기능 부여
내 코드 : order()
스프링 프록시 : (트랜잭션 시작) -> order() 실행 -> (커밋 / 롤백)
@GetMapping("/orders")
public void getOrders() {}
스프링 : "/orders 로 요청오면 이 메서드를 실행해야겠다"라고 등록
* 리플렉션 : 런타임에 클래스/메서드/필드를 읽는 자바 기능
@SpringBootApplication 실행
-> Component Scan 시작
-> @Service 감지 -> OrderService BeanDefinition 생성
-> @Controller 감지 -> OrderController BeanDefinition 생성
-> BeanDefinition 기반 빈 생성 및 의존성 주입
-> @GetMapping("/orders") -> HandlerMapping에 등록
* BeanDefinition : "어떤 방식으로 이 클래스를 빈을 만들지"를 담고 있는 스프링의 핵심 구조