본문 바로가기
2025 Dev Log/Tech Notes

[#4] 스프링 빈(Bean) 개념 정리

by Dev.후크리 2025. 9. 25.

그간 내가 쓰는 어노테이션들이 스프링 빈이란 것을 몰랐다.

써야 하니까 썼는데, 스레드를 자바로 구현하는 예시가 궁금해서 찾아보다 내가 빈에 대해 전혀 잘못 알고 있었다는 점을 알았다.

 

이런 당연한데 몰랐던 점들이 많은 것 같은데, 그 중 하나이기에 바로 기록해보려 한다.

 

1) 스프링 빈이란?
  • Bean(빈) = 스프링 컨테이너가 생성하고 관리하는 객체.
  • 개발자가 직접 new 하지 않고, 스프링이 대신 만들고 주입(Injection)해줌.
  • 빈은 이름(id)타입(class) 기준으로 컨테이너에 보관.

 


2) 주입(Injection)과 호출(Call)
  • 주입: 컨테이너가 필요한 객체를 컨트롤러/서비스 안에 “끼워 넣는” 과정.
    (예: 전기 플러그를 콘센트에 꽂아줌)
  • 호출: 실행 시점에 주입된 객체의 메서드를 사용하는 것.
    (예: 스위치를 눌러 전기를 쓰는 것)

👉 즉, 주입은 호출을 가능하게 해주는 준비 과정.


3) 빈 등록 방식 두 가지

 

(1) 자동 등록 (Auto Scanning)

  • @Component, @Service, @Controller, @Repository 같은 애너테이션 붙이면 자동 등록.
  • 스프링이 컴포넌트 스캔을 통해 컨테이너에 올려줌.
 
@Service
public class UserService { ... }

@RestController
public class UserController {
    private final UserService userService;
    public UserController(UserService userService) { // 자동 주입
        this.userService = userService;
    }
}

(2) 수동 등록 (Manual @Bean)

  • 직접 새로운 객체를 만들어서 빈으로 등록.
  • 주로 스레드풀, 외부 라이브러리 객체, 커스텀 설정 객체를 등록할 때 사용.
 
@Configuration
public class AsyncConfig {
    @Bean(name = "ioExecutor")
    public Executor ioExecutor() {
        ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor();
        ex.setCorePoolSize(8);
        ex.setMaxPoolSize(32);
        ex.initialize();
        return ex; // 이 객체가 컨테이너에 Bean으로 등록
    }
}

→ 이후 @Async("ioExecutor") 같은 방식으로 사용 가능.

 

 


4) 자동 등록 vs 수동 등록 요약

 

구분 자동 등록 수동 등록
방식 @Service, @Controller, @Component 등 @Configuration + @Bean
쓰임새 일반 비즈니스 로직 클래스 외부 라이브러리, 스레드풀, 커스텀 객체
개발자가 하는 일 클래스에 어노테이션만 붙임 객체 생성 코드를 직접 작성
컨테이너 입장 둘 다 똑같은 Bean으로 관리  

 


5) 실전 예시 (스레드풀 빈 등록 & 사용)
 
@Configuration
@EnableAsync
public class AsyncConfig {
    @Bean(name = "ioExecutor") // ioExecutor라는 이름으로 등록
    public Executor ioExecutor() {
        ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor();
        ex.setCorePoolSize(8);
        ex.setMaxPoolSize(32);
        ex.initialize();
        return ex;
    }
}

@Service
public class IoService {
    @Async("ioExecutor") // 등록된 ioExecutor 빈 사용
    public void fetch() {
        // 백그라운드 스레드에서 실행
    }
}

👉 핵심: 직접 만든 객체도 컨테이너에 등록만 하면, @Service 빈처럼 똑같이 주입/호출 가능.

 


✅ 한 줄 요약
  • 스프링 빈 = 컨테이너가 관리하는 객체.
  • 주입은 “연결”, 호출은 “실행”.
  • 자동 등록(@Service)과 수동 등록(@Bean) 모두 최종적으로는 같은 빈.
  • 직접 만든 스레드풀도 @Bean으로 등록하면, 서비스/컨트롤러에서 REST API와 똑같이 쉽게 사용 가능.