본문 바로가기
Java

Spring 컨트롤러 및 컴포넌트 정리

by Hwangminseo 2026. 4. 8.

1. RestfulController

REST 방식으로 /api/v1/members 요청을 처리하는 컨트롤러이다.

핵심 포인트

  • @RestController 사용
  • 기본 경로: /api/v1
  • GET /members 요청 시 문자열 응답 반환
  • 반환 문자열이 그대로 HTTP 응답 본문에 출력됨

코드

package idusw.sba.admin202212004a.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1")
public class RestfulController {
    @GetMapping("/members")
    public String getMemberList(){
        return "<h1>Member List</h1>";
    }
}

2. HomeController

화면 이동을 담당하는 기본 컨트롤러이다.

2-1. 초기 버전

특징

  • / 요청 시 p 파라미터를 받아 모델에 저장
  • 이후 redirect:/main/index로 리다이렉트
  • /main/index에서 실제 메인 화면 반환
  • /misc/cards에서 카드 화면 반환

코드

package idusw.sba.admin202212004a.controller;

import jakarta.annotation.Nullable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HomeController {
    @GetMapping("/")
    public String goHome(@Nullable @RequestParam("p") String p, Model model){
        model.addAttribute("attrname", p);
        return "redirect:/main/index";
    }

    @GetMapping("/main/index")
    public String goIndex(){
        return "main/index";
    }

    @GetMapping("/misc/cards")
    public String goCards(){
        return "./misc/cards";
    }
}

2-2. 수정 버전

변경 사항

  • @Nullableredirect:를 활용해 흐름을 분리
  • /에서는 단순히 메인으로 리다이렉트
  • p 파라미터 처리와 Model 저장 로직은 /main/index로 이동

코드

package idusw.sba.admin202212004a.controller;

import jakarta.annotation.Nullable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HomeController {
    @GetMapping("/")
    public String goHome(){
        return "redirect:/main/index";
    }

    @GetMapping("/main/index")
    public String goIndex(@Nullable @RequestParam("p") String p, Model model){
        model.addAttribute("attrname", p);
        return "main/index";
    }

    @GetMapping("/misc/cards")
    public String goCards(){
        return "./misc/cards";
    }
}

정리

  • redirect:/main/index는 브라우저에게 /main/index로 다시 요청하도록 지시한다.
  • @Nullable은 요청 파라미터 p가 없어도 오류가 나지 않게 한다.
  • 화면 반환 시 main/index는 보통 templates/main/index.html을 의미한다.

3. ErrorController

에러 페이지 전용 컨트롤러이다.

특징

  • /errors/404 요청 처리
  • 404 에러 화면 템플릿으로 이동

코드

package idusw.sba.admin202212004a.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/errors")
public class ErrorController {
    @GetMapping("/404")
    public String get404(){
        return "../errors/404";
    }
}

4. ProductController

상품 관련 화면 이동을 처리하는 컨트롤러이다.

4-1. 기본 버전

코드

package idusw.sba.admin202212004a.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/products")
public class ProductController {
    @GetMapping("/list")
    public String getProducts(){
        return "../products/list";
    }
}

4-2. cards 기능 추가 버전

HomeController에 있던 cards 기능을 ProductController로 이동한 형태이다.

코드

package idusw.sba.admin202212004a.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/products")
public class ProductController {
    @GetMapping("/list")
    public String getProducts(){
        return "../products/list";
    }

    @GetMapping("/cards")
    public String goCards(){
        return "../products/cards";
    }
}

정리

  • /products/list → 상품 목록 화면
  • /products/cards → 상품 카드 화면
  • 기능을 관련 컨트롤러로 옮겨 역할을 분리한 구조이다.

5. MemberController

회원 관련 화면 이동을 담당하는 컨트롤러이다.

코드

package idusw.sba.admin202212004a.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/members")
public class MemberController {
    @GetMapping("/list")
    public String getMembers(){
        return "../members/list";
    }
}

정리

  • /members/list 요청 처리
  • 회원 목록 템플릿으로 연결

6. 전체 흐름 변화 요약

구조 변화

  1. 초기에는 HomeController가 메인, 파라미터 처리, cards 화면까지 함께 담당했다.
  2. 이후 /는 단순 리다이렉트만 수행하도록 단순화했다.
  3. 상품 관련 기능은 ProductController로 분리했다.
  4. 회원 화면은 MemberController, 에러 화면은 ErrorController로 따로 구성했다.

의도

  • 컨트롤러 역할을 명확히 분리
  • URL 구조를 더 직관적으로 설계
  • 유지보수성과 확장성 향상

7. Spring 컴포넌트 개념 정리

사용자 메모에는 Spring의 컴포넌트 개념과 관련 링크가 함께 포함되어 있다.

Component

  • Spring이 자동으로 관리할 수 있는 클래스에 붙이는 기본 애너테이션
  • 컴포넌트 스캔 대상이 되어 Bean으로 등록될 수 있다.

Controller

  • 클라이언트 요청을 받아서 화면 또는 응답을 반환하는 역할
  • 주로 URL 매핑 담당

Service

  • 비즈니스 로직 담당
  • 컨트롤러와 저장소 사이의 처리 계층

Repository

  • 데이터 접근 담당
  • DB와 직접 연결되는 계층

ClassPathBeanDefinitionScanner

  • 클래스패스를 스캔하여 @Component 계열 애너테이션이 붙은 클래스를 찾아 Bean으로 등록하는 데 관련된 기능

8. Member 도메인 클래스

회원 정보를 담는 기본 도메인 객체이다.
Lombok 애너테이션을 사용해 getter, setter, 생성자, equals/hashCode, toString 등을 자동 생성한다.

추가로 @Bean(name="identifier") 메서드가 포함되어 있어 Spring 컨테이너에 이름이 identifier인 Bean을 등록하도록 구성되어 있다.

코드

package idusw.sba.admin202212004a.domain;

import lombok.*;
import org.springframework.context.annotation.Bean;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
public class Member {
    private long id;
    private String name;
    private String email;
    private String pw;

    @Bean(name="identifier")
    public Member getMembers(){
        return new Member();
    }
}

필드 설명

  • id: 회원 번호
  • name: 회원 이름
  • email: 회원 이메일
  • pw: 회원 비밀번호

추가된 Bean 메서드 정리

  • @Bean(name="identifier")
    • Spring 컨테이너에 identifier라는 이름으로 Bean을 등록할 때 사용된다.
  • getMembers()
    • 새로운 Member 객체를 생성해서 반환한다.
  • 반환 결과
    • 등록된 Bean 이름은 identifier가 된다.

참고할 점

  • 일반적으로 @Bean@Configuration 클래스 안에서 선언하는 경우가 많다.
  • 현재처럼 일반 도메인 클래스 내부에 @Bean 메서드를 두는 방식은 실습용으로는 볼 수 있지만, 보통의 실무 구조에서는 자주 쓰지 않는다.
  • 단순 데이터 객체인 Domain 클래스와 Spring 설정 역할이 한 클래스에 함께 들어간 형태라고 볼 수 있다.

9. application.properties 설정 추가

추가된 설정 파일 내용이다.

코드

spring.application.name=admin-202212004a
spring.thymeleaf.cache=false
server.port=9000

설정 의미

  • spring.application.name=admin-202212004a
    • 현재 Spring Boot 애플리케이션 이름을 지정한다.
  • spring.thymeleaf.cache=false
    • Thymeleaf 템플릿 캐시를 비활성화한다.
    • 화면 파일을 수정했을 때 서버 재시작 없이 변경 내용을 바로 확인하기 쉬워진다.
    • 개발 단계에서 자주 사용하는 설정이다.
  • server.port=9000
    • 내장 톰캣 실행 포트를 기본값 8080이 아니라 9000으로 변경한다.
    • 따라서 접속 주소는 보통 http://localhost:9000이 된다.

10. 최종 실행 화면

11. 정리

애너테이션 구분

  • @Controller: 뷰 반환
  • @RestController: 데이터 자체 반환
  • @RequestMapping: 공통 URL 지정
  • @GetMapping: GET 요청 처리
  • @Nullable: 값이 없어도 허용
  • @Bean: Spring 컨테이너에 관리 객체를 등록

redirect와 view 반환 차이

  • redirect:/main/index → 브라우저가 해당 주소로 다시 요청
  • main/index → 해당 뷰 템플릿을 바로 렌더링

이번 실습의 핵심

이번 내용은 Spring MVC에서 컨트롤러를 URL별로 분리하고, redirect, Model, @Nullable, @Controller, @RestController의 차이를 실습 코드로 익히는 과정이다.

또한 application.properties 설정을 통해 애플리케이션 이름, 템플릿 캐시 사용 여부, 실행 포트까지 함께 설정하는 기본 구조를 이해하고, Member 클래스에 추가된 @Bean 메서드를 통해 Spring Bean 등록 개념까지 함께 확인하는 단계라고 볼 수 있다.

'Java' 카테고리의 다른 글

차근차근 풀어가는 자바 기초 노트  (0) 2025.09.03