스프링에서 가장 많이 보이는 단어 4가지가 있습니다:
@Component, @Service, @Repository, @Controller모두 “스프링이 관리하는 객체(Bean)”를 만들기 위한 애너테이션이지만,
역할과 사용 위치가 각각 다릅니다.이번 글에서는 이 4개의 차이와 Bean의 개념,
스프링 컨테이너가 어떻게 작동하는지까지 완전히 이해할 수 있도록 설명합니다.
📌 목차
- Bean(빈)이란 무엇인가?
- 스프링 컨테이너란?
- @Component란?
- @Service란?
- @Repository란?
- @Controller / @RestController 차이
- 컴포넌트 스캔(Component Scan)의 원리
- Bean 등록 방식 2가지(@Component vs @Bean)
- 자주 하는 실수
- 대표 태그
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 개념 완전 정리 + 왜 분리해야 하는가?