1.4 스프링 주요 애너테이션(Annotation) 총정리
스프링 프레임워크는 설정의 상당 부분을 애너테이션을 통해 처리합니다. 각 기능별 핵심 애너테이션과 그 실전 사용 예제들을 한눈에 보기 쉽게 정리했습니다.
🏗️ 1. 스테레오타입 (Bean 등록 관련)
스프링 컨테이너(ApplicationContext)가 시작될 때, 컴포넌트 스캔(Component Scan)을 통해 해당 클래스를 메모리에 객체(Bean)로 로딩하게 만드는 표식들입니다.
@Component: 가장 기본적인 스프링 관리 빈의 역할을 수행합니다. 모든 기능성 클래스에 범용적으로 붙입니다.@Service: 비즈니스 로직(트랜잭션 처리, 도메인 로직 호출)을 담당하는 클래스에 명시합니다.@Repository: 데이터베이스 접속 계층(DAO) 클래스에 사용하며, 하위 DB 프레임워크의 예외를 스프링 전용 예외(DataAccessException)로 변환해주는 특수 기능이 내장되어 있습니다.@Controller: 전통적인 MVC의 HTML View 영역(JSP, 타임리프)을 반환하는 컨트롤러에 사용합니다.@RestController: HTML이 아닌 JSON이나 XML 등 순수 데이터를 반환하는 REST API용 컨트롤러에 사용합니다. (@Controller+@ResponseBody의 결합체)
// [스테레오타입 실전 적용 예시]
@Repository // 1. DB 접근 계층 로딩
public class MemberRepository {
public void save(Member member) { /* DB 저장 */ }
}
@Service // 2. 비즈니스 로직 계층 로딩
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository repository;
@Transactional
public void register(Member member) { repository.save(member); }
}
@RestController // 3. 외부 API 응답 컨트롤러 계층 로딩
@RequestMapping("/api/members")
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@PostMapping
public String join(@RequestBody Member member) {
memberService.register(member);
return "SUCCESS"; // JSON(문자열) 본문이 그대로 응답됨
}
}
💉 2. 의존성 주입 (DI) 및 수동 설정 관련
@Autowired: 스프링 컨테이너에 등록된 빈을 의존 관계에 따라 타입(Type)으로 찾아 자동으로 주입해줍니다. (최근에는 생성자 주입을 권장하여 자주 생략됨)@Qualifier("빈 이름"): 같은 타입의 인터페이스 구현체 빈이 2개 이상일 때, 충돌을 막고 정확히 어떤 이름의 빈을 꽂을지 지목합니다.@Configuration&@Bean: 개발자가 직접@Component를 붙일 수 없는 외부 라이브러리(Gson, RestTemplate 등)를 스프링 컨테이너에 수동으로 등록할 때 사용하는 세트입니다.
// [수동 빈 등록 예시]
@Configuration // "스프링아, 이 클래스는 빈 공장 세팅도면이야!"
public class AppConfig {
// 외부 라이브러리인 RestTemplate을 스프링 메모리에 1개(싱글톤) 올린다.
@Bean
public RestTemplate myRestTemplate() {
return new RestTemplate();
}
}
// [@Qualifier 주입 충돌 해결 예시]
@Service
public class OrderService {
private final DiscountPolicy discountPolicy;
// RatePolicy 와 FixPolicy 빈 2개가 등록된 상황에서 명확하게 타겟을 지정
public OrderService(@Qualifier("rateDiscountPolicy") DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
}
🌐 3. 스프링 MVC (웹 HTTP 통신) 관련
클라이언트의 브라우저에서 날아온 HTTP 요청 패킷을 자바 코드로 파싱하고 쪼개입는 라우팅 어노테이션들입니다.
@GetMapping,@PostMapping,@PutMapping,@DeleteMapping: 특정 HTTP 메서드와 URL 주소를 자바 메서드에 짝지어(매핑) 줍니다.@PathVariable: URL 주소 덩어리에 변형되어 들어온 값을 잘라옵니다. (/users/123-> 123)@RequestParam: URL 뒤에 물음표(?)로 붙는 쿼리스트링이나 HTML Form 데이터를 잘라옵니다. (/list?page=2-> 2)@RequestBody: 클라이언트가 보낸 HTTP 바디의 JSON 덩어리를 자바 객체(DTO)로 변형(역직렬화)해서 통째로 넣어줍니다.
// [스프링 MVC 어노테이션 총집합 API]
@RestController
@RequestMapping("/api/products") // 공통 URL 앞단을 모두 묶음
public class ProductController {
// GET /api/products/99 -> id 변수에 99 할당
@GetMapping("/{id}")
public ProductDto getProduct(@PathVariable("id") Long id) {
return productService.findById(id);
}
// GET /api/products/search?keyword=맥북&limit=10
@GetMapping("/search")
public List<ProductDto> search(
@RequestParam("keyword") String keyword,
@RequestParam(value = "limit", defaultValue = "20") int limit) {
return productService.search(keyword, limit);
}
// POST /api/products + JSON 바디 {"name": "아이폰", "price": 100}
// JSON 스트링이 통째로 ProductCreateRequest 자바 객체 필드로 꽂혀 들어옴!
@PostMapping
@ResponseStatus(HttpStatus.CREATED) // 성공 시 200 OK 대신 201 Created 지정
public void createProduct(@RequestBody ProductCreateRequest request) {
productService.create(request);
}
}
♻️ 4. 라이프사이클 및 인프라 프로퍼티 관련
@PostConstruct: 빈 객체가 생성되고@Autowired의존성 주입까지 완전 끝난 직후, 딱 1번 실행되는 초기 세팅 메서드.@PreDestroy: 서버가 꺼지기 직전 컨테이너가 죽을 때, 열어둔 통신 소켓이나 자원을 정리하려고 호출하는 메서드.@Value:application.yml에 적어둔 중요한 비밀번호나 속성값을 자바 변수 안으로 읽어올 때 씁니다.
// [라이프사이클 및 프로퍼티 주입]
@Component
public class AwsS3Uploader {
// application.yml 의 cloud.aws.s3.bucket 값을 찾아내어 bucket 필드에 강제 주입
@Value("${cloud.aws.s3.bucket}")
private String bucket;
@PostConstruct // 스프링 컨테이너가 이 클래스를 조립 완료하자마자 바로 실행!
public void initAwsConnection() {
System.out.println(bucket + " 버킷에 연결을 개통합니다. 준비완료!");
}
@PreDestroy // 톰캣 서버 셧다운 버튼 누르는 순간 실행!
public void closeAwsConnection() {
System.out.println("S3 소켓 연결을 안전하게 끊습니다.");
}
}
🛡️ 5. 유효성 검증(Validation) 및 기타 중요 어노테이션
@Transactional: 이 메서드 블록 시작할 때 트랜잭션 문을 열고, 메서드가 정상수행되어 닫히면Commit, 중간에 예외가 터지면Rollback처리를 완벽하게 자동화하는 마법의 어노테이션입니다.@Valid/@Validated: 파라미터로 날아온 자바 객체의 제약조건(빈 값을 안 넣었는지, 글자 수는 맞는지)을 1차 검열하는 보초병 역할을 합니다.@RestControllerAdvice: 전 프로젝트의 컨트롤러에서 터져나가는 모든 익셉션(에러)을 한 군데 모아서 처리해 주는 전역 예외 센터를 만듭니다.
// [유효성 검증 예시]
// DTO 클래스 정의
public class UserCreateRequest {
@NotBlank(message = "이름은 필수입니다!") // 빈 공백 금지
private String name;
@Min(value = 19, message = "미성년자는 불가능합니다.") // 최소 19 이상
private int age;
}
@RestController
public class UserController {
@PostMapping("/users")
// @Valid가 동작하여 들어온 JSON이 조건(나이 19살 이상)을 통과 못하면
// 메서드 진입도 못하고 프론트엔드로 400 Bad Request 에러를 팅겨냅니다.
public String createUser(@Valid @RequestBody UserCreateRequest request) {
userService.save(request);
return "가입 성공";
}
}
🎯 핵심 요점
- 애너테이션은 보일러플레이트 코드를 줄여주며, 설정의 생산성 을 놀랍게 끌어올려줍니다.
- 이러한 마법 뒤에는 언제나 스프링 컨테이너와 리플렉션(Reflection), AOP 프록시 라는 근간 기술이 보이지 않게 작동하고 있음을 기억해야 깊이 있는 학습이 가능합니다.