inblog logo
|
LifeLog, DevLog
    Spring

    알고 있어야할 어노테이션들 - 1

    컴포넌트의 등록, 요청, 응답 관련
    KYJTHEYJ's avatar
    KYJTHEYJ
    Dec 25, 2025
    알고 있어야할 어노테이션들 - 1
    Contents
    알고 있어야할 어노테이션들 - 1컴포넌트들의 등록의존성 주입하기HTTP 매핑 관련응답 처리 어노테이션

    알고 있어야할 어노테이션들 - 1

    컴포넌트들의 등록

    @Component

    일반 Bean 등록 → 스프링 컨테이너에 등록되어 재사용 가능한 컴포넌트 (Bean)
    더 쉽게 말해 스프링 컨테이너가 관리하는 객체

    @Component
    public class EmailSender {
        public void send(String email) { }
    }

    @Service

    주요 비즈니스 로직을 명시한 컴포넌트

    @Service
    public class UserService {
        public User findById(Long id) { }
    }

    @Repository

    주요 데이터 접근을 명시한 컴포넌트, DB의 예외가 Spring 예외로 변환됨

    @Repository
    public class UserRepository {
        public User save(User user) { }
    }

    @Controller

    요청을 분배, 처리하는 컨트롤러임을 명시한 컴포넌트

    @Controller
    public class UserController {
        @GetMapping("/users")
        public String list() { }
    }
    • RestController 와의 차이

      • Controller 는 일반적으로 View 를 반환함

      • 데이터를 JSON 형태로 반환하기 위해서는 @ResponseBody 사용해야함

        @Controller
        @RequestMapping("/api/users")
        public class UserApiController {
            
            @GetMapping
            @ResponseBody
            public List<User> getUsers() {
                return userService.findAll();
            }
        }
      • 하지만 RestController는 Controller + ResponseBody 의 형태
        매번 데이터 반환이 필요할 때 ResponseBody를 사용하지 않아도 됨

    💡

    모두가 사실 @Component의 특수 형태

    주로 역할을 명확히 하고 부가적인 기능을 제공


    의존성 주입하기

    @Autowired

    Spring 의 DI 에 따라, 스프링 컨테이너가 자동으로 Bean 주입하도록 요청하는 것

    @Service
    public class UserService {
        
        @Autowired
        private UserRepository userRepository;
    }
    • 위 컴포넌트 부분에서의 UserRepository 의 객체를 이 서비스의 userRepository 에 주입함

    • 개발자가 new 로 객체를 만드는 것이 아님

    💡

    다만 이러한 필드 주입은 더 이상 잘 사용되지 않는다
    외부에서 접근이 불가하고 수정할 수 없다 → 테스트가 힘들다

    생성자 주입에 대해서 많이 사용하고 있다

    생성자 주입 **

    @Service
    public class UserService {
        
        private final UserRepository userRepository;
        
        @Autowired  // 생성자 1개면 생략 가능
        public UserService(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    }

    @Qualifier

    같은 타입의 Bean 이 여러 개 일때 이름으로 선택하도록 하는 것

    // UserRepository 구현체가 2개
    @Component("mySQLUserRepository")
    public class MySQLUserRepository implements UserRepository { }
    
    @Component("mongoUserRepository")
    public class MongoUserRepository implements UserRepository { }
    
    @Service
    public class UserService {
        
        @Autowired
        @Qualifier("mySQLUserRepository") // 선택
        private UserRepository userRepository;
    }

    @Primary

    같은 타입의 Bean 이 여러 개 일때 우선적으로 선택하게 하는 것

    @Component
    @Primary  // ← 우선 선택
    public class MySQLUserRepository implements UserRepository { }
    
    @Component
    public class MongoUserRepository implements UserRepository { }
    
    @Autowired // 우선 선택된 컴포넌트가 주입됨
    private UserRepository userRepository; 

    💡

    @Qualifier > @Primary > 이름 매칭 순 으로 우선순위를 가짐


    HTTP 매핑 관련

    @RequestMapping

    url 경로로 선언된 HTTP 요청을 처리함

    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public String getUsers() { }

    다만 이제는 요청 메서드를 직접 명시할 수 있어, 이 부분이 더 많이 쓰임

    @GetMapping("/users")    // = @RequestMapping(method = GET)
    @PostMapping("/users")   // = @RequestMapping(method = POST)
    @PutMapping("/users")    // = @RequestMapping(method = PUT)
    @DeleteMapping("/users") // = @RequestMapping(method = DELETE)
    @PatchMapping("/users")  // = @RequestMapping(method = PATCH)

    @PathVariable

    url 경로에 선언된 부분을 파라미터로 바인딩 함

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) { }

    @RequestParam

    쿼리 파라미터를 자동으로 파라미터로 바인딩함

    // GET /search?keyword=spring&page=1
    @GetMapping("/search")
    public List<Product> search(@RequestParam String keyword,
                               @RequestParam int page) { }

    세부 옵션들

    @RequestParam(required = false)  // 필수 아님
    @RequestParam(defaultValue = "1")  // 기본값
    @RequestParam("q")  // 파라미터 이름 다를 때
    String keyword

    @RequestBody

    요청의 바디에 JSON을 자동으로 객체 변환 (보통 DTO의 객체로 변환)

    @PostMapping("/users")
    public User createUser(@RequestBody UserRequest request) { }

    @ModelAttribute

    요청의 바디가 Form일 경우 (application/x-www-form-urlencoded)
    자동으로 객체로 변환

    @PostMapping("/users")
    public String createUser(@ModelAttribute UserForm form) { }

    @RequestHeader

    헤더의 값을 파라미터로 바인딩

    @GetMapping("/users/me")
    public User getMe(@RequestHeader("Authorization") String token) { }
    
    요청:
    GET /users/me
    Authorization: test testing123
    
    token 의 값은 "test testing123"

    @CookieValue

    쿠키의 값을 파라미터로 바인딩

    @GetMapping("/users/me")
    public User getMe(@CookieValue("SESSION") String sessionId) { }
    
    요청:
    GET /users/me
    Cookie: SESSION=xyz789
             ↓
    쿠키 추출:
      sessionId = "xyz789"
    
    sessionId 의 값은 xyz789

    응답 처리 어노테이션

    @ResponseBody

    반환 값을 View 가 아닌 HTTP 의 바디로 보내라는 의미

    @Controller
    public class UserController {
        
        @GetMapping("/api/users")
        @ResponseBody
        public List<User> getUsers() {
            return userService.findAll();
        }
    }
    
    List<User> 데이터를 JSON으로 변환해서 Body에 담아 보냄!

    @ResponseStatus

    상태 코드를 설정함

    @PostMapping("/users")
    @ResponseStatus(HttpStatus.CREATED)  // 201
    public User createUser(@RequestBody UserRequest request) {
        return userService.create(request);
    }
    Share article
    Contents
    알고 있어야할 어노테이션들 - 1컴포넌트들의 등록의존성 주입하기HTTP 매핑 관련응답 처리 어노테이션

    LifeLog, DevLog - https://github.com/KYJTHEYJ

    RSS·Powered by Inblog