개발(React | Java)/자바 기초 | 문법

📘 Spring Boot 입문 (3)@Component / @Service / @Repository / @Controller 차이 + Bean 개념 완전 정리

dev-parrot 2025. 12. 11. 15:22

스프링에서 가장 많이 보이는 단어 4가지가 있습니다:
@Component, @Service, @Repository, @Controller

모두 “스프링이 관리하는 객체(Bean)”를 만들기 위한 애너테이션이지만,
역할과 사용 위치가 각각 다릅니다.

이번 글에서는 이 4개의 차이와 Bean의 개념,
스프링 컨테이너가 어떻게 작동하는지까지 완전히 이해할 수 있도록 설명합니다.


📌 목차

  1. Bean(빈)이란 무엇인가?
  2. 스프링 컨테이너란?
  3. @Component란?
  4. @Service란?
  5. @Repository란?
  6. @Controller / @RestController 차이
  7. 컴포넌트 스캔(Component Scan)의 원리
  8. Bean 등록 방식 2가지(@Component vs @Bean)
  9. 자주 하는 실수
  10. 대표 태그

1️⃣ Bean(빈)이란 무엇인가?

스프링이 직접 만들어서 관리하는 객체를 말합니다.

즉: new 객체생성 → 스프링이 대신 해준다

스프링은 Bean을 생성하고, 필요할 때 주입(DI)해주며, 생명주기까지 관리합니다.


2️⃣ 스프링 컨테이너란?

스프링 컨테이너는 Bean을 관리하는 “큰 통”이라고 보면 됩니다.

✔ 객체 생성
✔ 의존 관계 주입 @Autowired
✔ 생명주기 관리(초기화/종료)

이 모든 일을 대신해줍니다.


3️⃣ @Component — 가장 기본적인 스프링 빈 등록

@Component는
“이 클래스를 스프링 빈으로 등록해줘!”라는 의미입니다.

@Component
public class MailSender {
    ...
}

✔ 모든 스프링 빈의 부모 애너테이션
✔ Service/Repository/Controller도 결국 @Component의 특화 버전


4️⃣ @Service — 비즈니스 로직 담당

Service 계층에 사용하는 @Component의 특화 버전입니다.

@Service
public class UserService {
    ...
}

 

특징:

✔ 의미적으로 “서비스 레이어임”을 표현
✔ 트랜잭션 처리(@Transactional)과 함께 자주 사용
✔ 유지보수와 가독성 높아짐


5️⃣ @Repository — DB와 연결된 계층

DB 접근 계층에 사용하는 애너테이션입니다.

@Repository
public class UserRepository {
    ...
}

 

특징:

✔ DB 예외를 스프링 예외로 변환 (Spring Exception Translation)
✔ JPA에서는 인터페이스 형태로 사용

 

public interface UserRepository extends JpaRepository<User, Long> {}

 

6️⃣ @Controller vs @RestController

둘 다 Controller 계층이지만 반환 방식이 다릅니다.


✔ @Controller

View(HTML 템플릿)를 반환

@Controller
public class HomeController {
    @GetMapping("/")
    public String home() {
        return "index"; // templates/index.html
    }
}

 

✔ @RestController

문자열/JSON 데이터를 반환
(API 서버 만들 때 99% 사용)

@RestController
public class ApiController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

 

➡ @RestController = @Controller + @ResponseBody


7️⃣ 컴포넌트 스캔(Component Scan) 원리

스프링은 특정 패키지 안의 클래스를 자동으로 찾아서 Bean으로 등록합니다.

기본적으로:

@SprinBootApplication이 있는 패키지 하위만 스캔

 

예:

com.example.demo
 ├─ DemoApplication.java (@SpringBootApplication)
 └─ service/
 └─ controller/
 └─ repository/

 

➡ 이 구조라면 모든 하위 폴더의
@Controller, @Service, @Repository, @Component가 자동 등록됨.


8️⃣ Bean 등록 방식 2가지

스프링에서 빈을 등록하는 방법은 크게 두 가지입니다.


✔ 1) 자동 등록 (@Component 계열)

@Component
@Service
@Repository
@Controller

➡ 실무에서 90% 사용


✔ 2) 수동 등록 (@Bean)

설정 파일에서 직접 Bean을 만들어 등록하는 방식.

@Configuration
public class AppConfig {

    @Bean
    public EmailSender emailSender() {
        return new EmailSender("smtp server");
    }
}

 

수동 등록이 필요한 상황:

✔ 외부 라이브러리 객체를 Bean으로 등록할 때
✔ 생성 과정이 복잡한 객체를 제어하고 싶을 때


9️⃣ 자주 하는 실수

❌ Controller 레이어에서 비즈니스 로직 작성

→ 반드시 Service에서 처리해야 함

❌ @Autowired 필드 주입

→ 생성자 주입(권장 방식)으로 변경해야 함

❌ 컴포넌트 스캔 범위 밖에 파일 생성

→ Bean 등록 자체가 안 됨

❌ @RestController로 템플릿 반환하려 함

→ @Controller 사용해야 함

 

📘 다음 글 예고

👉 Spring Boot 입문 (4) — DTO, Entity, DAO 개념 완전 정리 + 왜 분리해야 하는가?