본문 바로가기
💻 하나씩 차곡차곡/Back-end

[스프링(Spring)] 어노테이션(Annotation)이란? (특징, 원리, 자주 쓰는 어노테이션 정리)

by 뚜루리 2024. 8. 2.
728x90
320x100

스프링에서 사용하는 어노테이션이 무엇인지, 어노테이션의 특징과 자주 쓰는 어노테이션에 대해서 정리해보자.

 

 


 

어노테이션(Annotation)이란?

어노테이션은 자바의 메타데이터(metadata)로, 코드에 대한 부가 정보를 제공하는 데 사용되며, 주석(comments)과 비슷하지만, 주석은 프로그램의 동작에 영향을 미치지 않는 반면, 어노테이션은 프로그램의 컴파일, 배포, 실행 과정에서 다양한 기능을 수행하도록 영향을 줄 수 있다.

 

어노테이션의 원리

스프링 프레임워크는 어노테이션을 사용하여 다양한 설정을 간편하게 처리하는데, 주로 **리플렉션(reflection)**과 프록시(proxy) 패턴을 사용하여 어노테이션의 동작을 구현한다.

  • 리플렉션: 런타임 시에 클래스, 메소드, 필드 등에 대한 정보를 동적으로 분석하고 조작할 수 있는 기능으로, 이를 통해 어노테이션이 붙은 클래스나 메소드를 찾아내어 설정을 적용한다.
  • 프록시: 실제 객체에 대한 대리 객체를 만들어 기능을 확장하거나 수정할 수 있는 패턴. 스프링은 AOP(Aspect-Oriented Programming) 기능을 제공하기 위해 프록시를 사용한다.

 

 


 

스프링부트의 주요 어노테이션

 

 

[설정에 관련된 어노테이션]

@SpringBootApplication

  • 스프링 부트 애플리케이션의 시작점으로, 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성이 모두 이 어노테이션을 통해 시작된다.
  • @Configuration, @EnableAutoConfiguration, @ComponentScan을 포함한다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MySpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }
}

 

@Configuration

  • 자바 기반의 설정 파일로, 스프링 컨텍스트를 구성하는 데 사용된다.
  • 스프링 빈을 정의하고 설정하는 클래스에 사용됩니다.
  • 내부에 정의된 @Bean 어노테이션이 붙은 메소드는 스프링 컨텍스트에 빈으로 등록됩니다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyService();
    }
}

 

@Bean

  • 메소드에 사용되어 해당 메소드의 반환 객체를 스프링 컨텍스트에 빈으로 등록한다.
  • @Configuration 어노테이션이 붙은 클래스 내에서 사용된다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyService();
    }
}

 

@EnableAutoConfiguration

  • 스프링 부트의 자동 구성 기능을 활성화하며, 주로 메인 애플리케이션 클래스에 사용됩니다.
  • 클래스에 사용되어 스프링 부트가 클래스패스 설정, 다양한 빈 설정, 기타 애플리케이션 설정을 자동으로 구성하도록 하며, 여러 조건을 기반으로 자동 구성 로직을 실행한다.
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
public class MyApplication {
    // 이 클래스는 자동 구성 기능을 활성화합니다.
}

 

 

@ComponentScan

 

  • 스프링이 컴포넌트를 검색하고 자동으로 빈으로 등록할 패키지를 지정하고, 주로 설정 클래스에 사용된다.
  • 지정된 패키지 및 하위 패키지에서 @Component, @Service, @Repository, @Controller 어노테이션이 붙은 클래스를 검색하여 빈으로 등록한다.
  • 하나 이상의 패키지를 지정할 수 있습니다.

 

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.example.myapp")
public class AppConfig {
    // 이 클래스는 스프링이 컴포넌트를 스캔할 패키지를 지정합니다.
}

 

 


[빈 등록에 관련된 어노테이션]

@Component

  • 스프링 컨텍스트에서 관리되는 일반적인 빈을 정의하며, 특별한 역할이 없는 모든 클래스에 사용될 수 있다.
  • 가장 기본적인 빈 정의 어노테이션으로, 다른 스테레오타입 어노테이션(@Service, @Repository, @Controller)의 기본 어노테이션이다.
import org.springframework.stereotype.Component;

@Component
public class MyComponent {
    public void doSomething() {
        System.out.println("Doing something in MyComponent");
    }
}

 

@Bean 과 @Component 둘 다 빈으로 등록되지만 @Bean 은 메소드 단위, @Component는 클래스 단위이다.

 

@Service

 

  • 서비스 계층의 빈을 정의하며, 비즈니스 로직을 처리하는 서비스 클래스에 사용된다.
  • 가독성과 의미 전달을 위해 @Component보다 더 구체적으로 사용된다.
import org.springframework.stereotype.Service;

@Service
public class MyService {
    public void performBusinessLogic() {
        System.out.println("Performing business logic in MyService");
    }
}

 

 

@Repository

 

  • 데이터 접근 계층의 빈을 정의하며, 데이터베이스와 상호작용하는 리포지토리 클래스에 사용된다.
  • 데이터 접근 예외를 스프링의 데이터 접근 예외로 변환하는 기능이 포함되어 있다.
  • 가독성과 의미 전달을 위해 @Component보다 더 구체적으로 사용된다.

 

import org.springframework.stereotype.Repository;

@Repository
public class MyRepository {
    public void accessData() {
        System.out.println("Accessing data in MyRepository");
    }
}

 

@Controller

  • 전통적인 스프링 MVC 컨트롤러로, 웹 요청을 처리하고 뷰(View)를 반환하는 데 사용된다.
  • 뷰 리졸버(View Resolver)를 통해 뷰 이름을 기반으로 실제 뷰(HTML, JSP 등)를 찾아 렌더링한다.
  • 주로 서버사이드 렌더링을 통해 HTML 페이지를 반환하는 경우 사용된다.
  • 메소드의 반환 값은 뷰 이름이며, Model 객체를 통해 뷰로 전달할 데이터를 설정할 수 있다.
  • 가독성과 의미 전달을 위해 @Component보다 더 구체적으로 사용된다.
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MyController {

    @GetMapping("/welcome")
    public String welcome(Model model) {
        model.addAttribute("message", "Welcome to the Spring MVC");
        return "welcome"; // 뷰 이름 반환 (예: welcome.jsp, welcome.html 등)
    }
}

 


 

@RestController

  • 주로 클라이언트(예: 웹 브라우저, 모바일 앱)에게 데이터를 제공하는 REST API를 작성할 때 사용된다.
  • JSON 또는 XML 형태의 데이터를 반환하는 데 사용됩니다. @Controller와 @ResponseBody의 결합이다.
  • @ResponseBody가 자동으로 적용되어 메소드의 반환 값을 HTTP 응답 본문에 직접 쓰기 때문에 별도의 뷰 리졸버가 필요 없다.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyRestController {

    @GetMapping("/api/welcome")
    public String welcome() {
        return "Welcome to the Spring REST API";
    }
}

 

 

@RestController VS @Controller

[반환 형태]

 

  • @Controller: 뷰 이름을 반환하고, 뷰 리졸버가 이를 실제 뷰로 변환하여 렌더링한다.
  • @RestController: JSON 또는 XML 데이터를 반환하며, 뷰 리졸버 없이 데이터 자체가 HTTP 응답 본문에 쓰인다.

 

[사용 목적]

 

  • @Controller: 주로 웹 애플리케이션에서 서버사이드 렌더링을 통해 HTML 페이지를 제공할 때 사용된다.
  • @RestController: RESTful 웹 서비스를 구현하여 클라이언트에게 JSON 또는 XML 형태의 데이터를 제공할 때 사용된다.

 


 

[요청/응답에 관련된 어노테이션]

@RequestMapping

  • HTTP 요청을 처리할 메소드나 클래스에 사용되며, URL 경로를 매핑한다.
  • 요청 URL, HTTP 메소드(GET, POST 등), 요청 매개변수 등을 매핑하여 해당 메소드가 호출되도록 한다.
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class ApiController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String getHello() {
        return "Hello from GET";
    }

    @RequestMapping(value = "/hello", method = RequestMethod.POST)
    public String postHello() {
        return "Hello from POST";
    }
}

 

 

@GetMapping, @PostMapping, @PutMapping, @DeleteMapping

  • @RequestMapping의 세부 버전으로, 각각 GET, POST, PUT, DELETE HTTP 메소드에 대한 매핑을 처리한다.
  • HTTP 메소드에 따라 요청을 처리할 메소드를 지정한다.
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/items")
public class ItemController {

    @GetMapping("/{id}")
    public String getItem(@PathVariable String id) {
        return "Get item " + id;
    }

    @PostMapping
    public String createItem() {
        return "Create item";
    }

    @PutMapping("/{id}")
    public String updateItem(@PathVariable String id) {
        return "Update item " + id;
    }

    @DeleteMapping("/{id}")
    public String deleteItem(@PathVariable String id) {
        return "Delete item " + id;
    }
}

 

@PathVariable

  • HTTP 요청의 경로 변수를 객체로 변환할 때 사용하는 어노테이션으로, 경로 변수는 URL의 일부로 전달됩니다.
  • 변수의 이름과 타입을 지정할 수 있다. 

 

 

@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
    // id 경로 변수를 사용하여 User 객체를 조회하고 반환
}

 

 

@RequestParam

  • HTTP 요청의 파라미터를 객체로 변환할 때 사용하는 어노테이션으로, 파라미터의 이름과 타입을 지정할 수 있습니다.
  • 필수 파라미터인지 여부를 지정할 수 있습니다.
@GetMapping("/user/{id}")
public User getUser(@RequestParam("name") String name, @RequestParam(required = false) String age) {
    // name과 age 파라미터를 사용하여 User 객체를 생성하고 반환
}

 

 

@RequestBody

  • HTTP 요청의 본문을 객체로 변환할 때 사용하는 어노테이션으로, 본문은 JSON, XML 등의 형식으로 전송된다.
  • 본문을 객체로 변환하기 위해 Jackson, Gson 등의 라이브러리를 사용한다.
@PostMapping("/user")
public void createUser(@RequestBody User user) {
    // user 객체를 사용하여 새로운 사용자 생성
}

 

@ModelAttribute

  • 컨트롤러에서 뷰로 전달할 객체를 지정할 때 사용하는 어노테이션으로 객체는 뷰에서 사용된다.
@GetMapping("/user/{id}")
public String getUser(@PathVariable Long id, Model model) {
    User user = userService.getUser(id);
    model.addAttribute("user", user);
    return "user/detail";
}

 

@ResponseBody

  • 컨트롤러에서 반환하는 객체를 HTTP 응답의 본문으로 전송할 때 사용하는 어노테이션으로, 본문은 JSON, XML 등의 형식으로 전송된다.
@GetMapping("/user/{id}")
@ResponseBody
public User getUser(@PathVariable Long id) {
    User user = userService.getUser(id);
    return user;
}

 

 

 

 


 

@Autowired

  • 스프링의 의존성 주입(DI)을 위해 사용되며, 스프링 컨텍스트에서 Bean을 자동으로 주입한다.
  • 타입에 따라 적절한 Bean을 찾아 주입한다. 생성자, 세터 메소드, 필드에 사용할 수 있다. 
  • 보통 생성자 주입에 많이 사용된다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    // ...
}

 

 

@Entity

  • JPA를 사용하여 데이터베이스 테이블과 매핑되는 엔티티 클래스를 나타낸다.
  • 클래스가 데이터베이스 테이블에 매핑되도록 하며, ORM(Object-Relational Mapping)을 통해 데이터베이스 작업을 처리한다.
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class MyEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and setters
}

 

 

@Transactional

  • 메소드 또는 클래스에 트랜잭션을 적용하여 데이터베이스 작업이 모두 성공적으로 완료되거나 모두 실패하도록 한다.
  • AOP를 사용하여 트랜잭션 시작, 커밋, 롤백 등의 트랜잭션 관리를 자동으로 처리한다.
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService {

    @Transactional
    public void performTransaction() {
        // transactional code
    }
}

 

 

 

 

 


  • 어노테이션 사용을 더욱 더 편리하게 만들어주는 롬복 라이브러리에 관하여

https://ddururiiiiiii.tistory.com/486

 

[스프링(Spring)] 롬복(Lombok) (롬복이란 / 자주 쓰는 기능 / @Data 사용을 지양해야 하는 이유 등)

롬복(Lombok) 이란?롬복(Lombok)은 자바 개발자들이 코드 작성을 더욱 편리하게 할 수 있도록 도와주는 라이브러리이다. 롬복(Lombok)의 특징컴파일 시점에 코드를 추가한다.별도의 라이브러리를 추

ddururiiiiiii.tistory.com

 

728x90
320x100