스프링 부트에서 어노테이션이 동작하는 원리

헨도·2025년 12월 2일

SpringBoot

목록 보기
39/41
post-thumbnail

작성한 이유

면접에서 대답하지 못했다.
이 질문을 대답하지 못한 것에 생각했는데, 개발할때 생각없이 사용하는 것만 신경써서 그런게 아닐까라는 고민을 했다..
내 방식에 대해 반성을 많이 하는 계기가 되었다.

어노테이션

스프링의 어노테이션은 그 자체로는 아무 동작을 하지 않는다.
어노테이션은 단지 "메타데이터"일 뿐이고, 스프링이 그 정보를 읽어서 동작을 만들어내는 구조이다.

동작과정

1. 스프링이 실행되면 클래스 스캔
2. 어노테이션 정보를 보고 빈 생성
3. @Autowired 같은 주입 어노테이션 읽고 의존성 주입
4. 일부 어노테이션은 스프링이 '프록시 객체'를 대신 만들어서 기능 부여
5. @GetMapping 같은 것들은 URL과 메서드 연결

1. 스프링이 실행되면 클래스 스캔

프로젝트 내 파일들을 찾으며, @Service, @Repository, @Controller 같은 어노테이션 탐색

@Service
public class OrderService() {}

스프링 : "이 클래스는 서비스구나, 빈으로 등록해야지"


2. 어노테이션 정보를 보고 빈 생성

스프링은 위에 붙어있는 어노테이션을 기준으로 클래스를 스프링 빈으로 등록

  • @Service -> 서비스 빈
  • @Controller -> 컨트롤러 빈
  • @Repository -> 레포지토리 빈

빈은 스프링이 대신 만들어서 관리해주는 객체


3. @Autowired 같은 주입 어노테이션을 읽고 의존성 주입

@Autowired
private OrderService orderService;

스프링 : "이 필드에 OrderService를 넣어줘야겠네"
-> 실제로 객체를 찾아서 필드에 넣어줌


4. 일부 어노테이션은 스프링이 '프록시 객체'를 대신 만들어서 기능 부여

@Transactional
public void order() { ... }

이 어노테이션은 :

  • 메서드를 실행하기 전에 트랜잭션을 시작하고
  • 끝난 후에 커밋 / 롤백을 결정하는 기능 필요

이 기능을 스프링이 어떻게 넣느냐?
-> 원본 객체를 감싸는 '프록시'를 만들어서 기능 부여

내 코드 : order()
스프링 프록시 : (트랜잭션 시작) -> order() 실행 -> (커밋 / 롤백)

5. @GetMapping 같은 어노테이션들은 URL과 메서드 연결

@GetMapping("/orders")
public void getOrders() {}

스프링 : "/orders 로 요청오면 이 메서드를 실행해야겠다"라고 등록


정리

  1. 어노테이션은 정보를 붙여놓는 표식이다.
  2. 스프링이 리플렉션으로 그 정보를 읽어서 빈 등록/주입/매핑을 자동으로 해준다.
  3. 트랜잭션이나 캐시 같은 것은 스프링이 프록시를 만들어 기능을 추가한다.

* 리플렉션 : 런타임에 클래스/메서드/필드를 읽는 자바 기능

실제 스프링 내부 흐름

@SpringBootApplication 실행
-> Component Scan 시작
-> @Service 감지 -> OrderService BeanDefinition 생성
-> @Controller 감지 -> OrderController BeanDefinition 생성
-> BeanDefinition 기반 빈 생성 및 의존성 주입
-> @GetMapping("/orders") -> HandlerMapping에 등록

* BeanDefinition : "어떤 방식으로 이 클래스를 빈을 만들지"를 담고 있는 스프링의 핵심 구조

profile
Junior Backend Developer

0개의 댓글