Spring/강의

[📕 기초 Spring] 4-1. 스프링 주요 어노테이션(Annotation)

가지코딩 2025. 5. 3. 19:49

📕 목차

  1. 어노테이션(Annotation)의 역할
  2. @Component, @Service, @Repository, @Controller, @RestController
  3. @Autowired
  4. @Value
  5. @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping
  6. @Bean
  7. @Transactional
  8. @PostConstruct, @PreDestroy
  9. @SpringBootApplication
  10. @Slf4j, @Log4j2, @Log
  11. 메타 어노테이션

강의에서 소개하는 어노테이션에 추가로

 

Spring에서 자주 사용되는 어노테이션들을 소개하고, 각 어노테이션의 사용 방법과 예제를 정리해보고자 한다.


1. 어노테이션(Annotation)의 역할

Spring에서 어노테이션

  • Spring Framework에서 어노테이션(Annotation) 은 코드에 메타데이터를 추가하여 특정 동작이나 설정을 정의하는 중요한 역할을 한다.
  • 어노테이션을 활용하면 Java 코드에 명시적인 설정을 추가할 수 있어, XML 설정 파일을 사용할 필요 없이 더 직관적이고 간결한 코드를 작성할 수 있다.
더보기
더보기
더보기

1. 의존성 주입(Dependency Injection)

  • Spring의 핵심 원칙 중 하나는 의존성 주입이다. 
  • 어노테이션을 사용하여 객체 간 의존 관계를 설정하고, Spring 컨테이너가 이를 관리하도록 할 수 있다.
  • 이를 통해 객체 생성을 Spring 컨테이너에 맡기고, 객체 간 결합도를 낮출 수 있다.

2. 컴포넌트 스캔(Component Scanning)

  • Spring은 어노테이션을 사용하여 클래스들이 Spring IoC 컨테이너에 의해 자동으로 관리될 수 있도록 한다.
  • 예를 들어, @Component, @Service, @Repository, @Controller 어노테이션을 사용하면, Spring은 해당 클래스를 자동으로 빈으로 등록하고 관리할 수 있다.

3. 트랜잭션 관리(Transaction Management)

  • 어노테이션을 사용하여 트랜잭션 관리의 범위를 정의할 수 있다.
  • @Transactional 어노테이션을 사용하면, 특정 메소드나 클래스에 대해 트랜잭션을 자동으로 시작하고, 예외 발생 시 롤백하는 등의 처리가 가능하다.

4. 설정(Configuration)

  • 어노테이션을 통해 Spring 설정을 Java 코드 내에서 정의할 수 있다.
  • @Configuration 어노테이션을 사용하여 설정 클래스를 정의하고, @Bean 어노테이션을 사용하여 빈을 설정할 수 있습니다. 이를 통해 XML 설정 대신 Java 기반 설정을 사용할 수 있다.

5. 애플리케이션 설정(Application Configuration)

  • Spring Boot에서는 @SpringBootApplication 어노테이션을 통해 애플리케이션의 시작점을 지정하고, 자동 설정 기능을 활성화하는 등 많은 설정을 한 번에 처리할 수 있다.

2. @Component, @Service, @Repository, @Controller, @RestController

Spring에서는 빈(Bean)을 정의할 때, 클래스에 @Component 또는 그 특화된 어노테이션을 사용할 수 있다.

  • @Component: 가장 일반적인 어노테이션으로, Spring IoC 컨테이너에 빈으로 등록된다.
  • @Service: 서비스 계층을 정의할 때 사용된다.
  • @Repository: 데이터 액세스 계층(DAO)을 정의할 때 사용된다.
  • @Controller: 웹 컨트롤러를 정의할 때 사용된다.
  • @RestController: @Controller@ResponseBody를 결합한 어노테이션으로, RESTful API를 제공한다.
// @Service 어노테이션을 사용한 서비스 클래스
@Service
public class UserService {
    public String getUser() {
        return "User";
    }
}

// @Controller 어노테이션을 사용한 컨트롤러 클래스
@Controller
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/user")
    public String getUser() {
        return userService.getUser();
    }
}

 

 

* 빈(Bean) 이란?

  • Spring Framework에서 관리되는 객체를 의미한다.
  • 스프링 컨테이너가 생성하고 관리하는 객체로, 주로 애플리케이션의 구성 요소를 나타낸다.

 

* @Controller vs RestController

항목 @Controller @RestController
목적 웹 페이지(view)를 반환하는 컨트롤러 RESTful API를 반환하는 컨트롤러
응답 뷰 이름(String)을 반환 객체를 반환하고 자동으로 JSON/XML로 변환
어노테이션 결합 @ResponseBody를 메서드에 추가해야 함 @ResponseBody가 기본적으로 적용됨

 


3. @Autowired

  • @Autowired는 의존성 주입(Dependency Injection)을 자동으로 처리해주는 어노테이션이다.
  • 필드, 생성자, 메소드에 적용할 수 있으며, Spring 컨테이너에서 관리하는 객체를 자동으로 주입한다.
@Component
public class UserService {
    public String getUser() {
        return "User";
    }
}

@Component
public class UserController {
    @Autowired
    private UserService userService;

    public String getUser() {
        return userService.getUser();
    }
}

4. @Value

  • 외부 설정 파일(application.properties 또는 application.yml)에서 값을 읽어 필드에 주입하는 데 사용된다.
@Component
public class AppConfig {
    @Value("${app.name}")
    private String appName;

    public void printAppName() {
        System.out.println("Application Name: " + appName);		// app.name=My Spring App
    }
}

5. @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping

  • HTTP 요청을 처리하는 메소드에 매핑하는 어노테이션이다.
  • @RequestMapping은 모든 HTTP 메소드에 대응할 수 있지만, @GetMapping, @PostMapping 등은 각 HTTP 메소드에 특화된 어노테이션이다.
@RestController
public class UserController {
    
    @GetMapping("/user")
    public String getUser() {
        return "User";
    }

    @PostMapping("/user")
    public String createUser(@RequestBody String user) {
        return "Created User: " + user;
    }
}

 

 

속성 설정

  • 특정 Parameter 매핑 가능
  • 특정 Header 매핑 가능
@RestController
public class ParameterController {

    // parms 속성값 추가
    @GetMapping(value = "/users", params = "gender=man")
    public String params() {
        String result = "params API가 호출 되었습니다.";
        return result;
    }
    
    // headers 속성값 추가
    @PostMapping(value = "/users", headers = "Content-Type=application/json")
    public String headers() {
        String result = "headers API가 호출 되었습니다.";
        return result;
    }
}

 

 

@PathVariable

  • 파라미터 변수명과 PathVariable 변수명이 같으면 속성 값 생략 가능
  • 다중 사용 가능
@RequestMapping("/posts")
@RestController
public class PathVariableController {
	
	@GetMapping("/{postId}")
	public String pathVariableV1(@PathVariable("postId") Long data) {
		String result = "PathvariableV1 결과입니다 : " + data;
		return result;
	}
    
    // 변수명과 같다면 속성값 생략가능
    @GetMapping("/{postId}")
	public String pathVariableV2(@PathVariable Long postId) {
		String result = "PathvariableV2 결과입니다 : " + postId;
		return result;
	}
    
    // 다중 사용 가능
    @GetMapping("/{postId}/comments/{commentId}")
	public String pathVariableV3(@PathVariable Long postId, @PathVariable Long commentId) {
		String result = "PathvariableV3 결과입니다 postId : " + postId + "commentsId : " + commentId;
		return result;
	}
}

6. @Bean

  • 메소드 수준에서 빈을 정의할 때 사용된다.
  • 이 메소드에서 반환하는 객체는 Spring IoC 컨테이너에 빈으로 등록된다.
@Configuration
public class AppConfig {
    
    @Bean
    public UserService userService() {
        return new UserService();
    }
}

7. @Transactional

  • 트랜잭션을 관리하는 어노테이션이다.
  • 트랜잭션을 시작하고, 예외가 발생하면 롤백하고, 성공적으로 완료되면 커밋된다.
@Service
public class UserService {

    @Transactional
    public void transferMoney() {
        // 여러 DB 작업이 있을 때 트랜잭션으로 관리
    }
}

8. @PostConstruct, @PreDestroy

  • @PostConstruct: 빈이 초기화된 후에 실행할 메소드를 지정하는 어노테이션입니다.
  • @PreDestroy: 빈이 소멸되기 전에 실행할 메소드를 지정하는 어노테이션입니다.
@Component
public class MyBean {

    @PostConstruct
    public void init() {
        System.out.println("Bean Initialized");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("Bean Destroyed");
    }
}

9. @SpringBootApplication

  • Spring Boot 애플리케이션의 진입점을 정의하는 어노테이션이다.
  • 이 어노테이션은 @Configuration, @EnableAutoConfiguration, @ComponentScan을 결합한 형태이다.
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

 

더보기
더보기
더보기

@Configuration

  • 해당 클래스가 스프링 설정 클래스임을 나타 내는 어노테이션이다.
  • 내부에 @Bean 메서드를 정의하면, 그 반환 객체가 Spring Bean으로 등록된다.
@Configuration
public class AppConfig {

    @Bean
    public UserService userService() {
        return new UserService();
    }
}

 

 

@EnableAutoConfiguration

  • Spring Boot에서 자동으로 설정을 활성화하는 어노테이션이다.
  • 기본적인 설정을 자동으로 처리하여, 개발자가 별도로 설정하지 않아도 필요한 설정들이 자동으로 적용된다.
@SpringBootApplication
@EnableAutoConfiguration
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

 

 

@ComponentScan

  • @Component, @Service, @Controller 등 컴포넌트 어노테이션이 붙은 클래스들을 스캔하여 빈으로 등록하는 어노테이션이다.
  • 기본적으로는 @ComponentScan이 붙은 클래스의 패키지 하위만 스캔한다.
@ComponentScan(basePackages = "com.example.service")
public class AppConfig {}

10. @Slf4j, @Log4j2, @Log

  • 로깅을 간편하게 처리하기 위한 어노테이션으로, Lombok 라이브러리에서 제공된다.
  • 코드에서 로그를 작성할 때, 추가적인 설정 없이 손쉽게 사용할 수 있다.
@Slf4j
@Service
public class UserService {

    public void logUserAction() {
        log.info("User action logged");
    }
}

11. 메타 어노테이션

메타 어노테이션은 일반적인 스프링 애플리케이션을 개발할 때 직접 자주 사용하는 어노테이션은 아니다.

 

하지만, 스프링 어노테이션의 구조나 원리를 이해하고, 커스텀 어노테이션 정의하기 위해서 반드시 알아야 할 핵심 개념이다.

 

 

@Target

  • 어노테이션을 어디에 적용할 수 있는지 지정한다.
  • 주요 ElementType
    • TYPE: 클래스, 인터페이스, enum
    • FIELD: 필드
    • METHOD: 메서드
    • PARAMETER: 메서드 파라미터
    • CONSTRUCTOR: 생성자
    • ANNOTATION_TYPE: 어노테이션 정의에 사용
@Target(ElementType.METHOD) // 메서드에만 붙일 수 있음
public @interface LogExecutionTime {
}

 

 

@Retention

  • 어노테이션을 언제까지 유지할 것인지를 정의한다.
  • 주요 RetentionPolicy
    • SOURCE: 컴파일 시 제거
    • CLASS: 클래스 파일까지 유지, 런타임에는 사용 불가 (기본값)
    • RUNTIME: 런타임까지 유지, 리플렉션으로 조회 가능
@Retention(RetentionPolicy.RUNTIME) // 런타임까지 유지
public @interface LogExecutionTime {
}

 

 

@Documented

  • 어노테이션이 Javadoc에 포함되도록 지정한다.
@Documented
public @interface LogExecutionTime {
}

 

 

@Inherited

  • 부모 클래스에 선언된 어노테이션이 자식 클래스에도 상속되도록 설정한다.
  • 클래스에만 적용된다. (@Target(ElementType.TYPE))
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
@MyAnnotation
class Parent {}

class Child extends Parent {}

// Child.class.isAnnotationPresent(MyAnnotation.class) 는 true 가 된다.