심화/Spring

[Spring] IoC Container와 Bean

annovation 2025. 10. 2. 09:31

Spring IoC 컨테이너

 

💡DI와 객체 생성

  • DI(의존성 주입)를 사용하려면 먼저 객체가 생성되어 있어야 한다.
  • 그런데 객체를 언제, 어디서, 누가 생성해야 할까? → 이 역할을 대신해 주는 것이 바로 Spring 프레임워크다.
  • Spring은 필요한 객체를 직접 만들고, 관리하고, 주입까지 해준다.

💡핵심 개념

  • 빈(Bean) : Spring이 관리하는 객체
  • Spring IoC 컨테이너 : 생성된 Bean들을 모아 관리하는 저장소

Spring 'Bean' 등록 방법

 

💡@Component

 

1️⃣ @Component 사용

@Component
public class MemoService { ... }
  • 클래스 위에 @Component 어노테이션을 붙이면 Spring이 자동으로 Bean으로 등록

2️⃣ Bean 저장 과정

// 1. MemoService 객체 생성
MemoService memoService = new MemoService();

// 2. Spring IoC 컨테이너에 Bean (memoService) 저장
// memoService -> Spring IoC 컨테이너
  • new MemoService() 처럼 객체를 생성한 뒤
  • Spring 서버가 Run될 때 IoC 컨테이너에 'Bean'을 저장 해준다.
  • 등록된 Bean의 이름은 클래스 이름에서 첫 글자를 소문자로 바꾼 것 ex. MemoService  memoService

3️⃣ Bean 아이콘 확인

Spring IoC 컨테이너에 저장된 Bean

  • 스프링 IoC 에서 관리할 'Bean' 클래스라는 표시

💡@ComponentScan

@Configuration
@ComponentScan(basePackages = "com.sparta.memo")
class BeanConfig { ... }
  • @Component로 등록된 클래스를 스캔하여 Bean으로 등록

@SpringBootApplication

  • 기본적으로 @SpringBootApplication에 포함되어 있어, 별도로 지정하지 않으면 현재 패키지와 하위 패키지 전부 스캔

Spring 'Bean' 사용 방법

 

💡@Autowired 사용

  • Spring IoC 컨테이너에 등록된 Bean을 자동으로 주입(DI, 의존성 주입)하는 방법

1️⃣ 필드 주입

@Component
public class MemoService {
		
    @Autowired
    private MemoRepository memoRepository;
		
		// ...
}
  • 필드 위에 @Autowired
  • Spring에서 IoC 컨테이너에 저장된 memoRepository ‘Bean’을 해당 필드에 DI 즉, 의존성을 주입 해줍니다.

2️⃣ 생성자 주입

@Component
public class MemoService {

    private final MemoRepository memoRepository;

    @Autowired
    public MemoService(MemoRepository memoRepository) {
        this.memoRepository = memoRepository;
    }
		
		// ...
}
  • 'Bean'을 주입할 때 사용할 메서드 위에 @Autowired
  • 객체의 불변성을 확보할 수 있기 때문에 일반적으로는 생성자를 사용하여 DI하는 것이 좋다.

3️⃣ Setter 주입

@Component
public class MemoService {
    private MemoRepository memoRepository;

    @Autowired
    public void setMemoRepository(MemoRepository memoRepository) {
        this.memoRepository = memoRepository;
    }
}
  • 필요 시점에 주입 가능하지만, 잘 쓰이지 않음

4️⃣ Lombok과 함께 사용

@Component
@RequiredArgsConstructor // final로 선언된 멤버 변수를 파라미터로 사용하여 생성자를 자동으로 생성합니다.
public class MemoService {

    private final MemoRepository memoRepository;
    
//    public MemoService(MemoRepository memoRepository) {
//        this.memoRepository = memoRepository;
//    }

		...

}
  • final 필드만 생성자 파라미터로 자동 주입

💡@Autowired 적용 조건

  • Spring IoC 컨테이너에 의해 관리되는 클래스에서만 가능
  • Spring IoC 컨테이너에 의해 관리되는 ‘Bean’객체만 DI에 사용될 수 있다.

💡@Autowired 생략 조건

public class A {
	public A(B b) { ... }
}
  • Spring 4.3 버젼 부터 @Autowired 생략가능
public class A {
	@Autowired // 생략 불가
	public A(B b) { ... }

	@Autowired // 생략 불가
	public A(B b, C c) { ... }
}
  • 단, 생성자 선언이 1개 일 때만 생략 가능

💡ApplicationContext 사용

@Component
public class MemoService {

		private final MemoRepository memoRepository;

    public MemoService(ApplicationContext context) {
        // 1.'Bean' 이름으로 가져오기
        MemoRepository memoRepository = (MemoRepository) context.getBean("memoRepository");

        // 2.'Bean' 클래스 형식으로 가져오기
        // MemoRepository memoRepository = context.getBean(MemoRepository.class);

        this.memoRepository = memoRepository;
    }

		...		
}
  • @Autowired로 Spring에 의해 자동으로 Bean을 주입 받지 않고 Spring IoC 컨테이너에서 Bean을 수동으로 가져오는 방법
  • ApplicationContext는 BeanFactory등을 상속하여 기능을 확장한 Container
    • BeanFactory는 ‘Bean’ 의 생성, 관계설정등의 제어를 담당하는 IoC 객체

3 Layer Annotation

3 Layer Annotation은 내부적으로는 모두 @Component 를 포함

💡3 Layer Annotation

  • 스프링에서 계층(layer)에 따라 역할이 다른 클래스를 Bean으로 등록하면서, 단순히 @Component 대신 의미 있는 어노테이션을 사용하도록 구분해둔 것
  • Spring 3 Layer Annotation은 Controller, Service, Repository의 역할로 구분된 클래스들을 ‘Bean’으로 등록할 때 해당 ‘Bean’ 클래스의 역할을 명시하기위해 사용된다.
    1. @Controller, @RestController
    2. @Service
    3. @Repository
  • Spring 3 Layer Annotation은 모두 @Component가 추가되어있다.

💡@Component 대신 쓰는 이유

  • 내부적으로는 모두 @Component를 포함하고 있어, Bean으로 등록되는 기능은 똑같음
  • 개발자가 한눈에 해당 클래스의 역할을 파악할 수 있음

출처

https://teamsparta.notion.site/2-5-IoC-Container-Bean-2252dc3ef514814bb8b2d98a9767cf8a

 

챕터2-5 : IoC Container와 Bean | Notion

Spring IoC 컨테이너

teamsparta.notion.site