스프링 - IoC Container와 Bean

2024. 8. 8. 16:54스프링

2024/08/08

 

 

※   IoC 컨테이너와 Bean에 대해 알아보자.

   ▶  Spring IoC 컨테이너

👉  지난 포스팅에서 DI를 사용했을 때의 장점을 알아보았다.
       
        그런데 DI를 사용하기 위해서는 객체 생성이 우선되어야 했다.
        그렇다면 언제❓, 어디서❓, 누가❓객체 생성을 해야 할까?
        바로 Spring 프레임워크가 필요한 객체를 생성하고 관리하는 역할을 대신 해준다.

       ●  빈(Bean) : Spring이 관리하는 객체
       ●  Spring IoC 컨테이너 : 'Bean'을 모아둔 컨테이너

 

   ▶  Spring 'Bean' 등록 방법

       ●  @Component
         ○  'Bean'으로 등록하고자 하는 클래스 위에 설정

@Component
public class MemoService { ... }


         ○  Spring 서버가 뜰 때 IoC 컨테이너에 'Bean'을 저장한다.
           -  @Component가 설정된 클래스에 대해서 Spring이 하는 일 확인하기

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

// 2. Spring IoC 컨테이너에 Bean (memoService) 저장
// memoService -> Spring IoC 컨테이너

           -  Spring 'Bean' 이름 : 클래스의 앞글자만 소문자로 변경
              EX)  public class MemoService ➡️ memoService

         ○  'Bean' 아이콘 확인 ➡️ 스프링 IoC에서 관리할 'Bean' 클래스라는 표시(인텔리제이의 경우)

 

       ●  @ComponentScan
         ○  Spring 서버가 뜰 때 @ComponentScan에 설정해 준 packages 위치와 하위 packages 들을 전부 확인하여
             @Component가 설정된 클래스들을 ‘Bean’으로 등록한다.

@Configuration
@ComponentScan(basePackages = "com.sparta.memo")
class BeanConfig { ... }

         ○  @SpringBootApplication에 의해 default 설정되어 있다.
              EX)  com.sparta.memo/MemoApplication.java

 

 

   ▶  Spring 'Bean' 사용 방법

       ●  @Autowired
         ○  필드 위에 @Autowired

@Component
public class MemoService {
		
    @Autowired
    private MemoRepository memoRepository;
		
		// ...
}

           -  Spring에서 IoC 컨테이너에 저장된 memoRepository ‘Bean’을 해당 필드에 DI 즉, 의존성을 주입해준다.

         ○  'Bean'을 주입할 때 사용할 메서드 위에 @Autowired

@Component
public class MemoService {

    private final MemoRepository memoRepository;

    @Autowired
    public MemoService(MemoRepository memoRepository) {
        this.memoRepository = memoRepository;
    }
		
		// ...
}

           -  객체의 불변성을 확보할 수 있기 때문에 일반적으로는 생성자를 사용하여  DI하는 것이 좋다.   
           -  set… Method를 만들고 @Autowired를 적용하여 DI 할 수도 있다.

         ○  @Autowired 적용 조건
           -  Spring IoC 컨테이너에 의해 관리되는 클래스에서만 가능

               ✅ 당연한 말이지만 Spring IoC 컨테이너에 의해 관리되는 ‘Bean’객체만 DI에 사용될 수 있다.

         ○  @Autowired 생략 조건
           -  Spring 4.3 버젼 부터 @Autowired 생략 가능
           -  단, 생성자 선언이 1개일 때만 생략 가능

public class A {
	public A(B b) { ... }
}

                ■  오버로딩된 생성자들

public class A {
	@Autowired // 생략 불가
	public A(B b) { ... }

	@Autowired // 생략 불가
	public A(B b, C c) { ... }
}

           -  Lombok의 @RequiredArgsConstructor를 사용하면 다음과 같이 코딩 가능

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

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

		...

}

 

       ●  ApplicationContext
         ○  ApplicationContext는 BeanFactory등을 상속하여 기능을 확장한 Container
           -  BeanFactoryBean’ 의 생성, 관계 설정 등의 제어를 담당하는 IoC 객체

         ○  스프링 IoC 컨테이너에서 ‘Bean’을 수동으로 가져오는 방법

@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;
    }

		...		
}

 

       ●  3 Layer Annotation
         ○  Spring 3 Layer Annotation은 Controller, Service, Repository의 역할로 구분된 클래스들을 ‘Bean’으로 등록할 때
             해당 ‘Bean’ 클래스의 역할을 명시하기위해 사용된다.
                1. @Controller, @RestController
                2. @Service
                3. @Repository

         ○  앞으로는 @Component가 아닌 3 Layer Annotation을 사용해서 ‘Bean’으로 등록하자.
             💡 Spring 3 Layer Annotation은 모두 @Component가 추가되어있다.

 

 

 

 

오늘은 스프링의 기본 개념인 IoC 컨테이너와 Bean에 대해 알아보았습니다.

 


※ 위 이미지들은 스파르타코딩클럽에 저작권이 있으므로 무단 도용 금지 및 상업 목적으로 사용할 수 없습니다.

'스프링' 카테고리의 다른 글

스프링 - 영속성 컨텍스트란?  (0) 2024.08.13
스프링 - Entity란?  (0) 2024.08.12
스프링 - Spring Data JPA란 무엇일까?  (0) 2024.08.09
쿠키와 세션이란 무엇일까?  (0) 2024.08.05
스프링 - IoC와 DI의 개념  (0) 2024.08.02