annotation
아래에는 제가 이번 전공동아리 과제를 하며 쓴 BoardController 코드 입니다. 이 코드로 예시를 들어 설명 해 보겠습니다.
우선 어노테이션은 사전적 의미로는 "주석"을 뜻합니다. 그러나 우리가 평소 C,Java를 공부 할 때 사용하는 //, /**/와는 조금
다릅니다. Spring,Java 등에서 쓰이는 어노테이션은 일반적인 주석과 다르게 코드를 작성 할 수 있습니다. 즉, 프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것이 어노테이션 입니다.
어노테이션은 주석이기 때문에 다이나믹하게 실행되는 코드는 들어가지 않습니다. 런타임 중에 알아내야 하는 값처럼 동적으로
바뀌는 값은 어노테이션에 쓸 수 없습니다. 컴파일러 수준에서 해석이 되거나, 완전히 정적이어야 어노테이션에 쓸 수 있습니다.
어노테이션을 선언하는 방법은 아래 코드에 보이는 것 처럼 앞에 @을 붙여서 선언합니다. @RestController @RequiredArgsContructor 과 같이 선언하게 됩니다. 즉 어노테이션은 개발자가 이 클래스/메서드/변수는 이런 역할을 해 라고 스프링에게 알려주는 도구입니다.
아래 코드에 있는 어노테이션 중 세가지에 대해서 설명 해 보겠습니다.
1. @RequiredArgsConstructor
롬복(Lombok)에서 제공하는 어노테이션으로, 클래스 내의 final이 붙은 필드들을 매개변수로 하는 생성자를 자동으로 생성해주는 역할을 합니다. 이를 통해 스프링에서 권장하는 생성자 기반의 의존성 주입을 간결하게 구현할 수 있으며, 명시적으로 생성자를
작성하지 않아도 되어 코드가 깔끔하고 유지보수가 쉬워집니다. 스프링에서는 생성자가 하나뿐일 경우, 해당 생성자를 통해 자동으로 의존성을 주입하므로 @Autowired 없이도 필요한 객체가 주입됩니다.
2. @PathVariable
스프링 프레임워크에서 제공하는 어노테이션으로, URL 경로에 포함된 값을 메서드의 파라미터로 바인딩할 때 사용됩니다.
예를 들어 localhost:8080/boards/1과 같은 요청이 들어오면, {id} 자리에 해당하는 1이라는 값을 추출해 변수에 저장하여 메서드 내부에서 사용할 수 있도록 도와줍니다. RESTful API를 설계할 때 자주 사용되며, URL 구조를 더욱 직관적이고 유의미하게 만들어 줍니다.
3. @RestController
스프링에서 제공하는 어노테이션으로, 이 클래스가 RESTful 웹 서비스를 처리하는 컨트롤러임을 나타냅니다.
내부적으로 @Controller와 @ResponseBody를 합친 기능을 하며, 메서드의 반환값을 뷰(View)로 처리하지 않고 HTTP 응답 본문(Response Body)에 JSON 또는 문자열 형태로 직접 반환하게 합니다.
따라서 REST API 서버를 개발할 때 자주 사용되며, 프론트엔드와 데이터를 주고받는 데 매우 효율적인 방식입니다.
package com.example.board.crud.controller;
import com.example.board.crud.dto.BoardListResponseDto;
import com.example.board.crud.dto.BoardRequestDto;
import com.example.board.crud.dto.BoardResponseDto;
import com.example.board.crud.service.BoardService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequiredArgsConstructor
public class BoardController {
private final BoardService boardService;
@PostMapping("/boards")
public BoardResponseDto createBoard(@RequestBody BoardRequestDto requestDto) {
BoardResponseDto board = boardService.createBoard(requestDto);
return board;
}
@GetMapping("/boards")
public List<BoardListResponseDto> getAllBoards() {
return boardService.findAllBoard();
}
@GetMapping("/boards/{id}")
public BoardResponseDto getOneboard(@PathVariable long id) {
return boardService.findOneBoard(id);
}
@PutMapping("/{id}")
public BoardResponseDto updateBoard(@PathVariable long id, @RequestBody BoardRequestDto requestDto) {
return boardService.updateBoard(id, requestDto);
}
@DeleteMapping("/boards/{id}")
public Long deleteBoard(@PathVariable long id) {
return boardService.deleteBoard(id);
}
@GetMapping("/boards/check/{id}/{inputPassword}")
public boolean checkPassword(@PathVariable long id, @PathVariable String inputPassword) {
return boardService.checkPassword(id, inputPassword);
}
}
import
import는 자바에서 다른 패키지에 정의된 클래스, 인터페이스, 어노테이션 등을 현재 클래스 파일에서 사용할 수 있도록 불러오는 명령어입니다. 기본적으로 자바는 java.lang 패키지를 제외하면 외부 클래스나 어노테이션을 자동으로 인식하지 않기 때문에, 사용하려는 객체가 속한 패키지를 import문을 통해 명시적으로 선언해야 합니다. 예를 들어, @RestController 어노테이션을
사용하려면 해당 어노테이션이 정의된 org.springframework.web.bind.annotation.RestController를 import해야 합니다.
import는 코드의 가독성을 높이고, 같은 이름의 클래스가 여러 패키지에 있을 경우 정확한 경로를 지정함으로써 충돌을 방지하는 데도 도움이 됩니다. import는 "내 프로젝트 안에 있는 다른 라이브러리나 도구 상자를 가져오는 것"입니다. 가져오지 않으면
사용할 수 없어요. 마치 책을 읽기 전에 책장에서 꺼내오는 느낌이라고 할 수 있겠습니다.
그런데 위 코드에서 import가 하는 일은 무엇이고 import를 쓰지 않는다면 무슨 일이 일어날까요?
1. import java.util.List;
이 import는 Java 표준 라이브러리에서 제공하는 List 인터페이스를 현재 클래스에서 사용할 수 있도록 불러옵니다.
List는 여러 개의 데이터를 순서대로 저장할 수 있는 자료형이며, 예제 코드에서는 게시글 목록을 담기 위해 사용되고 있습니다.
만약 이 import 구문이 없으면, List<BoardListResponseDto>처럼 List라는 이름을 사용할 수 없기 때문에
컴파일 오류가 발생합니다. IDE에서는 "Cannot resolve symbol 'List'" 또는 "List cannot be resolved to a type"와 같은
오류 메시지를 보여주게 됩니다.

위 사진은 제가 작성한 BoardController 코드 입니다. import java.util.List; 를 주석처리 했더니 List 부분에
Cannot resolve symbol 'List' 라며 오류가 나는 것을 알 수 있습니다.
2. import lombok.RequiredArgsConstructor;
이 import는 Lombok 라이브러리에서 제공하는 @RequiredArgsConstructor 어노테이션을 사용하기 위해 필요한 선언입니다.
@RequiredArgsConstructor는 클래스의 final 필드에 대해 자동으로 생성자를 만들어주기 때문에, 생성자 기반의 의존성 주입을 간결하게 구현할 수 있습니다. 이 import가 없으면 @RequiredArgsConstructor를 사용할 수 없게 되어, 컴파일러가 해당
어노테이션의 정의를 찾지 못하므로 "Cannot resolve symbol" 오류가 발생합니다.

방금과 같이 import lombok.RequiredArgsConstructor; 부분에 주석처리를 하니
Cannot resolve symbol 오류가 발생하게 되었습니다.
3. import org.springframework.web.bind.annotation.*;
이 import는 @RestController, @PostMapping, @GetMapping, @PutMapping, @DeleteMapping, @PathVariable, @RequestBody 등 스프링 MVC에서 제공하는 모든 웹 관련 어노테이션들을 한꺼번에 불러오는 역할을 합니다.
별도로 하나하나 import하지 않고도 여러 개의 어노테이션을 사용할 수 있어 편리합니다.
이 import가 없으면 위에서 나열한 모든 어노테이션(@RestController, @GetMapping 등)을 사용할 수 없으며, 컴파일러가 해당 어노테이션을 인식하지 못하게 됩니다.

import org.springframework.web.bind.annotation.*; 스프링 MVC에서 제공하는 모든 웹 관련 어노테이션들을 한꺼번에
불러오는 역할을 하기 때문에 주석처리를 했을 때 수 많은 Cannot resolve symbol 오류가 발생 하는 걸 볼 수 있습니다.
4. import com.example.board.crud.dto.BoardListResponseDto;
이 import는 BoardListResponseDto 클래스를 현재 컨트롤러에서 사용할 수 있도록 불러오는 선언입니다.
BoardListResponseDto는 게시글 목록을 담아 프론트엔드로 응답할 때 사용되는 DTO(Data Transfer Object)로, getAllBoards() 메서드의 반환 타입으로 사용됩니다. 이 import가 없으면 BoardListResponseDto라는 클래스를 찾을 수 없기 때문에,
"Cannot resolve symbol 'BoardListResponseDto'"라는 컴파일 오류가 발생하며 해당 메서드는 작동하지 않게 됩니다.
import com.example.board.crud.dto.BoardRequestDto;
import com.example.board.crud.dto.BoardResponseDto;
import com.example.board.crud.service.BoardService;
등의 import도 이와 같은 역할을 하는 import 입니다.

import com.example.board.crud.dto.BoardListResponseDto; 에 주석처리를 했더니
BoardListResponseDto라는 클래스를 찾을 수 없게 되어서
Cannot resolve symbol 'BoardListResponseDto' 오류가 발생 하게 되는걸 볼 수 있습니다.
이처럼 각 import는 클래스나 어노테이션을 현재 파일에서 사용할 수 있도록 해주는 필수 요소이며, 없으면 코드가 실행은커녕
컴파일조차 되지 않습니다. 저는 이번 전공동아리 과제인 Spring으로 게시판 CRUD 만들기를 하며 import가 다르다거나 오타를
찾지 못해 고생을 한 경험 등을 해보았기에 어노테이션과 import의 역할, 없으면 생기는 오류 등을 공부 해 볼 수 있는 기회가
되었기에 좋은 경험이라고 생각합니다. 마지막으로 공부하며 헷갈리거나 몰랐던 단어 한 줄 설명하고 블로그 마치겠습니다.
읽어주셔서 감사합니다.
파라미터: 메서드나 함수에 전달되는 입력값.
바인딩: 외부 입력값을 변수나 객체에 연결하는 과정.
RESTful API: 웹의 자원들을 HTTP 방식으로 표현하고 통신하는 규칙.
JSON: 데이터를 키-값 쌍으로 표현하는 가볍고 읽기 쉬운 데이터 형식.
DTO: 계층 간 데이터 전달을 위한 객체(Data Transfer Object).
클래스: 객체를 만들기 위한 설계도 또는 틀.
'Spring' 카테고리의 다른 글
| [Spring] Servlet과 DispatacherServlet (2) | 2025.08.01 |
|---|---|
| [Spring] Spring Filter란? (2) | 2025.08.01 |
| [Spring] PSA란? (0) | 2025.07.22 |
| [Spring] IoC란? (0) | 2025.07.17 |
| [Spring] DI란? (0) | 2025.07.16 |