[Spring] IoC 컨테이너와 Bean

이병수·2024년 1월 22일
0

스프링 정리

목록 보기
8/24

IoC 컨테이너와 Bean


스프링 컨테이너 ( = IoC 컨테이너 )

객체를 생성하고 관리하고 책임지며 의존성을 관리해주는 스프링 프레임워크내의 컨테이너이다.
이때 스프링 컨테이너에서 생성되는 객체를 Bean 이라고 한다.

인스턴스 생성부터 소멸까지의 인스턴스 생명주기 관리를 개발자가 아닌 컨테이너가 해준다.

따라서 개발자는 로직에 집중 할 수 있게 된다.


IoC 의 분류

  • DL(Dependency Lookup)

    • 저장소에 저장되어 있는 Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 Lookup하는 것
  • DI(Dependency Injection)

    • 각 클래스 간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결

    • Constructor Injection (생성자 주입)

    • Setter Injection (수정자 주입)

    • Field Injection (필드 주입)

주로 DI를 사용한다. (DL을 사용하면 컨테이너 종속이 증가하기 때문)


스프링 컨테이너 종류

  1. BeanFactory

    • BeanFactory 계열의 인터페이스만 구현한 클래스는 단순히 컨테이너에서 객체를 생성하고 DI를 처리하는 기능만 제공

    • Bean을 등록, 생성, 조회, 반환 관리를 한다.

    • Bean을 조회할 수 있는 getBean() 메서드가 정의

    • 보통 BeanFactory를 바로 사용하지 않고 ApplicationContext를 사용한다.

  2. ApplicationContext

    • Bean을 등록, 생성, 조회, 반환하는 기능은 BeanFactory와 같다.

    • 스프링의 각종 부가 기능을 추가로 제공한다.

      • 국제화가 지원되는 텍스트 메시지 관리
      • 이미지 같은 자원을 로드할 수 있는 포괄적인 방법 제공
      • 리스너로 등록된 빈에게 이벤트 발생 알림

빈 팩토리보다 어플리케이션 콘텍스트를 사용하는것이 더 좋음



Bean

스프링 컨테이너에 등록한 객체들을 이라고 한다.

  • Bean Container 는 의존성 주입(DI)을 통해 Bean 객체를 사용할 수 있도록 해준다.

  • 보통 Bean은 싱글톤 패턴으로 존재하게 된다.

@Controller
public class MemberController { // -> memberController 로 빈 이름이 등록
	...
}
  • 빈으로 등록하게 되면 빈 이름은 설정할 때의 클래스의 앞글자만 소문자로 변경이 된다.

Bean 설정 방법

@Controller
public class MemberController {
	...
}
  1. @ComponentScan이 @Component 어노테이션이나 @Service, @Controller, @Repository등 어노테이션이 부여된 클래스를 찾아 자동으로 Bean 등록

    • 해당 어노테이션들은 모두 @Component 어노테이션을 포함하고 있다.

    • @ComponentScan은 해당 패키지 , 하위 패키지 들을 전부 확인하여 @Component가 설정된 클래스들을 빈으로 등록한다.


@Configuration
public class SpringConfig {
	@Bean
    public MemberService memberService() { ... }
   
}
  1. ApplicationContext 를 통해 수동으로 스프링 빈 등록

    • 자바 설정 클래스를 따로 만들어서 사용해야한다.

    • 설정 클래스 위에 @Configuration 어노테이션을 추가한다.

    • 특정 타입을 리턴하는 메서드를 만들고, @Bean 어노테이션을 붙이면 빈 객체가 생성이 된다.


등록된 스프링 빈 사용

@Autowired 사용

빈들을 등록하고 필요한 곳에서 @Autowired 를 통해 의존성 주입을 받아 사용한다.

의존성 주입 : 필요한 객체에서 직접 생성하는 것이 아닌 외부로부터 객체를 받아서 사용


주의! : @Autowired는 IoC 컨테이너에 의해 관리되고 있는 Bean 클래스 내부에서만 적용이 가능


의존성 주입의 3가지 방법

  1. 생성자 주입 (Constructor Injection)
@Controller
public class TestController {
	private final TestService testService;
    
    @Autowired
    public TestController(TestService testService) {
    	this.testService = testService;
    }
}
  • 클래스의 생성자가 하나이고, 생성자로 주입받을 객체가 빈으로 등록되어 있다면 @Autowired를 생략할 수 있다.

  1. 필드 주입 (Field Injection)
@Controller
public class TestController {
	@Autowired
	private TestService testService;
}
  • 필드에 직접 @Autowired 어노테이션을 붙인다.

  • 다만, 외부에서 변경하기 힘들다는 점, 프레임워크에 의존적이며 객체지향적으로 좋지 않음


  1. 수정자 주입 (Setter Injection)
@Controller
public class TestController {
	private TestService testService;
    
    @Autowired
    public void setController(TestService testService) {
    	this.testService = testService;
    }
}
  • Setter 메서드에 @Autowired 어노테이션을 붙임

  • 언제 어디서든 변경이 가능하다는 점에서 좋지 않다.


생성자를 통한 주입이 권장하는 방법이다.

왜냐?

  • final로 선언하여 객체의 불변성을 보장하기 때문이다.

  • 테스트에 용이하다는 점


스프링 컨테이너 순서

스프링이 시작하게 되면

  1. @ComponentScan 애노테이션을 통해 해당 패키지, 하위 패키지 내의 모든 @Component 애노테이션을 찾아 빈으로 등록

  2. 등록이 된 후, @Autowired 즉, DI(의존성 주입)이 필요한 것들에게 등록된 빈들을 주입하여 객체를 생성

profile
백엔드 개발자가 되고 싶어요

0개의 댓글