#1 IoC 컨테이너
스프링 에플리케이션에서는 오브젝트의 생성, 관계 설정, 사용 제거 등의 작업을 코드가 아닌 독립된 컨테이너가 담당한다. 컨테이너가 오브젝트 제어권을 가지고 있기 때문에 IoC (Inversion of Control) 라고 부른다.
스프링에서는 IoC 담당 컨테이너를 빈 팩토리 / 애플리케이션 컨텍스트라고 부르기도 한다.
IoC 컨테이너를 이용한 애플리케이션 생성
ApplicationContext 구현 클래스의 인스턴스를 만듦으로써 간단하게 IoC 컨테이너를 만들 수 있다.
StaticApplicationContext ac = new StaticApplicationContext();
StaticApplicationContext는 ApplicationContext 인터페이스를 구현한 클래스다.
POJO 클래스
만들어진 컨테이너가 동작하기 위해서는, 첫 번째로 POJO 클래스가 필요하다. 각자의 기능에 충실하게 독립적으로 설계된 POJO 클래스를 만들고,결합도가 낮은 유연한 관계를 가질 수 있도록 인터페이스로 연결해준다.
메타정보
두 번째로, 만든 POJO 클래스들 중 애플리케이션에서 사용할 것을 선정한 뒤 IoC 컨테이너가 제어할 수 있도록 메타정보를 만들어 제공한다.
IoC 컨테이너가 사용하는 빈 메타정보
- 빈 아이디, 이름, 별칭 : 빈 오브젝트를 구분할 수 있는 식별자
- 클래스 또는 클래스 이름: 빈으로 만들 POJO 클래스 또는 서비스 클래스 정보
- 스코프: 싱글톤, 프로토타입과 같은 빈의 생성 방식과 존재 범위
- 프로퍼티 값 또는 참조: DI에 사용할 생성자 파라미터 이름과 값 또는 참조할 빈의 이름
- 생성자 파라미터 값 또는 참조 : DI에 사용할 생성자 파라미터 이름과 값 또는 참조할 빈의 이름
- 지연 로딩 여부, 우선 빈 여부, 자동와이어링 여부, 부모 빈 정보, 빈팩토리 이름 등
IoC 컨테이너 종류와 사용법
Application Context의 대표적인 4가지
- StaticApplicationContext
- GenericApplicationContext
- GenericXmlApplicationContext
- WebApplicationContext : 스프링 애플리케이션에서 가장 많이 사용된다.
웹 애플리케이션에서 만들어지는 스프링 IoC 컨테이너는 WebApplicationContext 인터페이스를 구현한 것이다.
웹 애플리케이션의 IoC 컨테이너 구성
웹 애플리케이션 안에서 동작하는 IoC 컨테이너는 2가지 방법으로 만들어진다.
- 스프링 애플리케이션의 요청을 처리하는 서블릿 안에서
- 웹 애플리케이션 레벨에서
일반적으로 위 두 가지 방식을 모두 사용해 컨테이너를 만든다. 따라서, 스프링 웹 애플리케이션에는 두 개의 컨테이너(WebApplicationContext 오브젝트)가 만들어진다. 스프링 애플리케이션의 프론트 컨트롤러 서블릿이 한 개 이상 등록된다면, 전체 컨테이너 개수는 늘어나게 된다.
웹 애플리케이션 레벨에서 등록되는 컨테이너는 보통 root web application context라고 불린다. 이 컨텍스트는 서블릿 레벨에 등록되는 컨테이너들의 부모이자 루트 컨텍스트가 된다. 일반적으로는 스프링의 애플리케이션 컨텍스트를 가지면서 프론트 컨트롤러 역할을 하는 서블릿은 하나만 만들어 사용한다. 아래와 같이 메서드를 이용해서 스프링 밖의 어디서라도 루트 애플리케이션 컨텍스트를 얻을 수 있다. 매개변수인 ServletContext는 웹 애플리케이션마다 하나씩 만들어지는 것이다.
// 루트 애플리케이션 컨텍스트를 얻는 방법
WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)
웹 애플리케이션의 컨텍스트 구성
애플리케이션 컨텍스틑 구성하는 방법으로는 3가지를 고려해 볼 수 있다.
- Servlet Context 와 Root Application Context 계층구조 - 가장 많이 사용되는 기본 구성 방법
- Root Application Context 단일구조
- Servlet Context 단일구조
#2 IoC/DI를 위한 Bean 설정 메타정보 작성
컨테이너는 빈 설정 메타정보를 통해 빈의 클래스와 이름을 제공 받는다. 빈 설정 메타정보는 파일이나 어노테이션 등의 리소스로부터 전용 리더를 통해 읽혀서 BeanDefinition 타입의 오브젝트로 변환된다. IoC 컨테이너는 이 BeanDefinition 정보를 활용하게 된다.
Bean 등록 방법
빈 등록은 메타정보를 작성하여 컨테이너에게 건네주면 된다. 스프링에서 자주 사용되는 방법은 크게 5가지가 있다.
- XML: <bean> 태그
- XML: 네임스페이스와 전용 태그
- 자동인식을 이용한 빈 등록 (스테레오 타입 어노테이션과 빈 스캐너)
- 자바 코드에 의한 빈 등록 (@Configuration 클래스의 @Bean 메소드)
- 자바 코드에 의한 빈 등록: 일반 빈 클래스의 @Bean 메소드
자동인식을 이용한 빈 등록 (스테레오 타입 어노테이션과 빈 스캐너)
XML 문서와 같이 한 곳에 명시적으로 선언하지 않고 스프링 빈을 등록하는 방법이다. 빈으로 사용될 클래스에 특별한 어노테이션을 부여하면 해당 클래스를 자동으로 찾아 빈으로 등록해준다.
이런 스캐닝 작업을 담당하는 오브젝트를 Bean Scanner라고 한다. Bean Scanner는 @Component 또는 @Component를 메타 어노테이션으로 가진 어노테이션이 부여된 클래스를 선택하도록 되어있다. 이렇게 적용되는 어노테이션을 스프링에서는 stereotype annotation이라고 부른다.
* 메타 어노테이션: 어노테이션의 위에 붙은 어노테이션
자바 코드에 의한 빈 등록 (@Configuration 클래스의 @Bean 메소드)
자바 코드를 통해 하나의 클래스 안에 여러 개의 빈을 정의할 수 있다. 또, 어노테이션을 이용하여 메타정보를 추가할 수 있다.
- 빈 설정 메타정보를 담고 있는 자바 코드는 @Configuration 어노테이션이 달린 클래스를 이용해 작성한다. 이 클래스 또한 빈으로 등록된다.
- @Bean 어노테이션이 붙은 메소드를 이용해서 빈을 만들 때 싱글톤의 경우 하나의 오브젝트만 생성되도록 @Bean 메소드를 조작해두었기 때문에, @Bean 메소드를 여러 번 호출해도 매번 동일한 빈 오브젝트가 리턴된다.
- @Configuration 클래스는 빈 스캐너를 동해 자동 등록될 수도 있다. (@Configuration의 메타 어노테이션에 @Component가 있음)
#3 Bean 오브젝트 사이 DI 설정을 위한 DI 메타정보 작성 방법
DI 대상 선정 방법으로 분류
- ID를 직접 지정 - 명시적으로 구체적 빈 지정
- 자동 와이어링 - 규칙에 따라 자동 선정
메타정보 작성 방법
- XML <bean> 태그
- 스키마를 가진 전용 태그
- 어노테이션 @Resource, @Autowired
- 자바 코드에 의한 직접 DI
@Resource
- Setter - 대표적인 DI
- 필드
- DAO에 DataSource를 의존 주입
@Resource
- Setter / 필드
- 생성자 - 생성자의 모든 파라미터에 auto wiring 적용
Spring DI
- Setter: 선택적으로 주입
- 생성자: 객체 불변성 보장
- 필드: 테스트 확장성에서 제한 사항 발생
- 메소드: 동적으로 주입
생성자 주입의 필요성
- 불변성: 시스템 안정성 향상
- 명시성: 어떤 의존성을 필요로 하는지 명확히 알 수 있음
- 테스트 용이성: Mock 객체로 쉽게 교체 가능
- 순환 의존성 감지: 순환 의존성 문제 발생시 감지하고 에러 발생
'Backend > Spring' 카테고리의 다른 글
[Spring] 주요 개념 총정리 (0) | 2024.04.18 |
---|---|
[Spring] JPA 연관관계 매핑 (0) | 2024.04.12 |
[Spring] JDBC, JDBC Template (0) | 2024.04.07 |
[Spring] REST API (0) | 2024.04.07 |