Spring Annotation 정리

niireymik·2024년 2월 15일

❄️ Annotation이란?

: Java5부터 새롭게 추가된 문법 요소이다. 사전적으로는 "주석"의 의미이지만 자바 코드에서 Annotation(@)코드 사이에 특별한 의미, 기능을 수행하도록 하는 기술이다. 프로그램 코드의 일부가 아닌, 프로그램에 관한 데이터를 제공하고 코드에 정보를 추가하는 정형화된 방법이다. 어노테이션을 사용하면 코드가 깔끔해지고 재사용이 가능하다.



🔥 Spring Annotation의 종류


@Controller

: Spring MVC의 Controller를 의미하며, 클래스 선언을 단순화시켜준다.

@RestController

: Spring에서 Controller 중 View로 응답하지 않는 Controller를 의미한다. 이는 메서드의 반환 결과를 JSON 형태로 반환한다. @RestController 가 적혀 있는 컨트롤러의 메서드는 HttpResponse로 바로 응답이 가능하다. 즉, @ResponseBody 역할을 자동적으로 해준다.

💡 @Controller와 @RestController의 차이점
@Controller
: API와 View를 동시에 사용하는 경우에 사용하며, API 서비스로 사용하는 경우는 @ResponseBody를 사용하여 객체를 반환한다. 이는
View return이 주목적이다.
@RestController
: View가 필요 없는 API만 지원하는 서비스에서 사용하며, @RequestMapping 메서드가 기본적으로 @ResponseBody 의미를 가진다. 이는 data Return이 주목적이다.

➡️ @RestController = @Controller + @ResponseBody

@Service

: 비즈니스 로직을 수행하는 클래스임을 나타내며, Service 클래스에서 쓰인다.

@Repository

: DAO 클래스에서 쓰이는 어노테이션으로서, DB에 접근하는 메서드를 가지고 있는 클래스에서 쓰인다.


@RequestMapping

: 어떤 URL을 어떤 메서드가 처리할지 매핑해주며, Controller의 메서드에 적용한다. 요청을 받는 형식인 GET/POST/PUT/DELETE(/PATCH)를 정의하기도 하는데, 정의하지 않을 경우 GET으로 자동 설정된다.

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

-> @RequestMapping(Method=RequestMethod.GET)과 같은 역할을 하는 것이 @GetMapping이다. 다른 어노테이션도 동일하다.

@RequestBody

: 요청이 온 데이터를 바로 Class 혹은 Model로 매핑하기 위한 어노테이션이다. HTTP POST (혹은 PUT/PATCH) 요청에 대해 request body에 있는 request message에서 값을 얻어와서 바로 모델이나 클래스로 매핑[파싱]해준다.

@RequestParam

: HTTP GET 요청의 request 파라미터 값을 가져올 때 사용한다. 즉, 메서드 파라미터에 사용하면서 ?name=Kim 과 같은 쿼리 파라미터를 파싱해 준다.

예시
http://localhost:8080/home?user_id=Kim

@GetMapping("/account")
public List<AccountInfo> getAccountByUserId ( @RequestParam("user_id") Long userId) {
...
}

@PathVariable

: 메서드 파라미터 앞에 사용하면서 해당 URL에서 {특정 값}을 변수로 받아올 수 있다. URI에서 각 구분자에 들어오는 값을 처리해야 할 때 사용하며, 주로 REST API에서 값을 호출할 때 많이 사용한다.
(RequestParam과 유사하다.)

예시
http://localhost:8080/api/posts/1

@GetMapping("/api/posts/{id}")   
public PostResponseDto getPost(@PathVariable Long id) {
	return postService.getPost(id);
}

@ResponseBody

: View가 아닌 JSON 형식으로 응답할 때 사용되는 어노테이션으로, 문자열을 리턴하면 그 값이 http response header가 아닌 response body에 들어간다.
(View가 아니라 함은, ViewResolver가 사용되어 View를 내보내는 MVC형식이 아닌 데이터를 바로 보내는 API형식임을 말한다.)

이는 @RestController가 이미 붙어 있다면 쓸 필요가 없다. 단순 컨트롤러가 HttpResponse로 응답할 수 있게 해준다.

  • 기본 문자처리: StringHttpMessageConverter
  • 기본 객체처리: MappingJackson2HttpMessageConverter

위처럼, 보내려는 데이터가 단순 문자면 StringConverter, 객체이면 JsonConverter가 동작한다. viewResolver를 무시한다고 보면 되겠다.


@Bean

: 개발자가 작성한 메서드를 통해 반환되는 객체를 Bean으로 만든다.

@SpringBootApplication

: Spring Boot를 자동으로 실행시켜주는 어노테이션으로, Bean 등록은 두 단계로 진행된다. (Bean : 스프링 컨테이너에 의해 인스턴스화되어 조립되거나 관리되는 객체)

@ComponentScan을 통해 Component들을 Bean으로 등록한다.
@EnableAutoConfiguration을 통해 미리 정의해둔 자바 설정 파일들을 Bean으로 등록한다.

@Component

: 개발자가 직접 작성한 클래스를 Spring Bean으로 자동 등록한다. @Component 를 포함하는 다음 어노테이션도 스프링 빈으로 자동 등록한다.

  • @Controller
  • @Service
  • @Repository

Component에 대한 추가 정보가 없다면 클래스의 이름을 camelCase로 변경한 것이 Bean id로 사용된다. 하지만 @Bean과 달리 @Component는 name이 아닌 value를 이용해 Bean의 이름을 지정한다.

@ComponentScan

: @Component, @Controller, @Service, @Repository, @Configuration이 붙은 빈들을 찾아서 Context에 등록해 준다.

(+) Spring에서 @Component로 다 쓰지 않고 @Repository, @Service, @Controller 등을 사용하는 이유는 다양하다. 문제 해결을 쉽게 하거나 가독성을 높여주는 것이 그에 해당한다.

@Configuration

: 스프링 컨테이너에게 해당 애노테이션이 붙은 클래스가 Bean으로 구성된 클래스임을 알려준다.

@EnableAutoCongiguration

: 사전에 정의한 라이브러리들을 Bean으로 등록해준다. (특정 조건을 만족하는 라이브러리만 등록된다.)


@Autowired

: 필드, setter 메서드, 생성자에 사용하며 타입에 따라 자동으로 Bean [객체에 대한 의존성] 을 주입시킨다.

Bean을 주입받는 방식(3가지)
1. @Autowired
2. setter
3. 생성자 : @AllArgsConstructor 사용, 스프링에서는 생성자를 통한 방식을 권장한다.

@Test

: Junit에서 테스트할 대상을 표시한다.

@AfterEach

: 한 번에 여러 테스트를 실행하면 메모리 DB에 직전 테스트의 결과가 남을 수 있다. 이렇게 되면 이전 테스트 때문에 다음 테스트가 실패할 가능성이 있다. @AfterEach를 사용하면 각 테스트가 종료될 때마다 이 기능을 실행한다.

‼️ 테스트는 각각 독립적으로 실행되어야 한다. 테스트 순서에 의존관계가 있는 것을 좋은 테스트가 아니다.

@AfterEach는 다음과 같이 작성할 수 있다.

@AfterEach
public void afterEach() {
	repository.clearStore();
 }

@BeforeEach

: 각 테스트 실행 전에 호출된다. 테스트가 서로 영향이 없도록 항상 새로운 객체를 생성하고, 의존 관계도 새로 맺어준다.

@SpringBootTest

: 스프링 컨테이너와 테스트를 함께 실행한다.

@Transactional

: 테스트 케이스에 이 애노테이션이 있으면, 테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백한다. 이렇게 하면 DB에 데이터가 남지 않으므로 다음 테스트에 영향을 주지 않는다.
(@AfterEach 에서 언급한 것처럼, 테스트는 '여러 번 실행할 수 있어야 한다'라는 조건을 가지므로 이는 중요하다!)


JPA Annotation

@Entity

: JPA를 사용해 테이블과 클래스를 매핑해준다. 이를 사용해 JPA가 해당되는 클래스를 관리하게 된다. 이는 DB의 테이블과 일대일로 매칭되는 객체 단위로, Entity 객체의 인스턴스 하나가 테이블에서 하나의 레코드 값을 의미한다.

@Id

: 특정 속성을 기본키(Primary Key)로 설정한다.

@GeneratedValue

: 기본키 값을 자동으로 생성해 준다. PK 컬럼의 데이터 타입은 정해져 있지는 않지만, 구분 가능한 유일한 값을 가지고 있어야 하며, 데이터를 합치며 발생하는 문제를 방지하기 위해 대부분 BigInteger 즉 Java의 LONG을 주로 사용한다.

@Column

: 객체 필드를 테이블 컬럼과 1:1 매핑한다. 쉽게 말해, Entity 클래스 안에 내부 변수로 정의된 Column 하나가 DB 테이블의 컬럼 하나를 의미하는 것이다.

이때 @Column 어노테이션은 별다른 옵션을 설정하지 않는다면 생략이 가능하다. 즉 Entity 클래스에 정의된 모든 내부변수는 기본적으로 @Column 어노테이션을 포함한다고 볼 수 있다.


Lombok Annotation

@Getter

: 클래스의 모든 필드에 Getter method를 자동으로 생성해 준다.

@Setter

: 클래스의 모든 필드에 Setter method를 자동으로 생성해 준다.

@AllArgsConstructor

: 클래스의 모든 필드 값을 파라미터로 받는 생성자를 자동으로 생성해 준다.

@NoArgsConstructor

: 클래스의 기본 생성자를 자동으로 생성해 준다.

@ToString

: 클래스의 모든 필드의 toString method를 자동으로 생성해 준다.


🤗 지금까지 알아본 Spring의 Annotation은 "주석"이란 뜻도 있지만, 자바 코드에서는 '특별한 의미, 기능을 부여하는 방법' 정도의 역할을 한다고 이해할 수 있었다. (앞으로 수도 없이 쓸 테니) 오늘 다룬 주요 어노테이션은 숙지해두자!

0개의 댓글