공부해봅시당

[스프링] 오브젝트와 의존관계 5 본문

STUDY/Spring

[스프링] 오브젝트와 의존관계 5

tngus 2022. 10. 28. 05:46

1.5. 스프링의 IoC

1.5.1. 오브젝트 팩토리를 이용한 스프링 IoC

애플리케이션 컨텍스트와 설정정보

스프링 빈(Bean)

- 스프링이 제어권을 가지고 직접 만들고 관계를 부여하는 오브젝트
- 자바빈 또는 엔터프라이즈 자바빈(EJB)에서 말하는 빈과 비슷한 오브젝트 단위의 애플리케이션 컴포넌트를 말함
- 스프링 컨테이너가 생성과 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트
※ 빈 팩토리와 애플리케이션 컨텍스트는 기본적으로 같은 의미

빈 팩토리(Bean Factory) > 빈을 생성하고 관계를 설정하는 IoC의 기본 기능에 초점


- 빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트


애플리케이션 컨텍스트(Application Context) > 애플리케이션 전반에 걸쳐 모든 구성요소의 제어 작업을 담당하는 IoC 엔진이라는 의미가 더 부각

- 빈 팩토리의 확장 개념
- IoC 방식을 따라 만들어진 일종의 빈 팩토리
- 별도의 정보를 참고해 빈(오브젝트)의 생성, 관계설정 등의 제어 작업 총괄

 


참고글

※ 아래에서 내용이 다시 등장할 예정

[ 애플리케이션 컨텍스트(Application Context)란? ]

Spring에서는 빈의 생성과 관계설정 같은 제어를 담당하는 IoC(Inversion of Control) 컨테이너인 빈 팩토리(Bean Factory)가 존재

실제로는 빈의 생성과 관계설정 외에 추가적인 기능이 필요
이러한 이유로 Spring에서는 빈 팩토리를 상속받아 확장한 애플리케이션 컨텍스트(Application Context)를 주로 사용

애플리케이션 컨텍스트는 별도의 설정 정보를 참고하고 IoC를 적용하여 빈의 생성, 관계설정 등의 제어 작업을 총괄

애플리케이션 컨텍스트에는 직접 오브젝트를 생성하고 관계를 맺어주는 코드가 없고, 그런 생성 정보와 연관관계 정보에 대한 설정을 읽어 처리

예를 들어 @Configuration과 같은 어노테이션이 대표적인 IoC의 설정정보
[ 빈(Bean) 요청 시 처리 과정 ]

클라이언트에서 해당 빈을 요청하면 애플리케이션 컨텍스트는 다음과 같은 과정을 거쳐 빈을 반환

1. ApplicationContext는 @Configuration이 붙은 클래스들을 설정 정보로 등록해두고, @Bean이 붙은 메소드의 이름으로 빈 목록을 생성
2. 클라이언트가 해당 빈을 요청
3. ApplicationContext는 자신의 빈 목록에서 요청한 이름이 있는지 찾음
4. ApplicationContext는 설정 클래스로부터 빈 생성을 요청하고, 생성된 빈 반환

<애플리케이션 컨텍스트(Application Context)와 스프링의 싱글톤(Singleton)>에 대한 추가 글

 


 

DaoFactory를 사용하는 애플리케이션 컨텍스트

DaoFactory를 스프링의 빈 팩토리가 사용할 수 있는 본격적인 설정정보로 만드는 작업

 

@Configuration 애노테이션

스프링이 빈 팩토리를 위한 오브젝트 설정을 담당하는 클래스라고 인식할 수 있도록 함
@Bean 애노테이션

오브젝트를 만들어주는 메소드에 붙임
ex) userDao(), connectionMaker()에 붙임

 

DaoFactory.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

...

@Configuration // 애플리케이션 컨텍스트 또는 빈 팩토리가 사용할 설정정보라는 표시
public class DaoFactory {
	@Bean // 오브젝트 생성을 담당하는 IoC용 메소드라는 표시
    public UserDao userDao() {
    	return new UserDao(connectionMaker());
    }
    
    @Bean
    public ConnectionMaker connectionMaker() {
    	return new DConnectionMaker();
    }
}

 

UserDaoTest.java < 애플리케이션 컨텍스트 적용

public class UserDaoTest {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
    	ApplicationContext context = new AnnotationConfigApplicationContext(DaoFactory.class);
        UserDao dao = context.getBean("userDao", UserDao.class);
        ...
    }
}

 

getBean() 메소드

ApplicationContext가 관리하는 오브젝트를 요청하는 메소드

1. 매개변수
    ex) getBean("userDao", UserDao.class); // 위에서 사용했던 코드
    1) 첫번째 파라미터 > "userDao"
        a) ApplicationContext에 등록된 빈의 이름
        b) 메소드 이름이 빈의 이름으로 등록됨
            (DaoFactory에서 @Bean이라는 어노테이션을 userDao라는 이름의 메소드에 붙임)
        c) userDao라는 이름의 빈을 가져온다는 것의 의미 > DaoFactory의 userDao() 메소드를 호출한 결과를 가져옴
        d) UserDao를 생성하는 방식이나 구성을 다르게 가져갈 수 있기 때문에 메소드명으로 빈 생성
            (specialUserDao()라는 메소드 만들고 getBean("specialUserDao", UserDao.class)로 가져옴)
    2) 두번째 파라미터 > UserDao.class
        - 위 클래스를 가져온다는 의미 > 아래 리턴에서 추가 설명

2. 리턴
    - Object 타입으로 리턴
        > 매번 리턴되는 오브젝트에 다시 캐스팅을 해줘야 하는 부담
        > 자바 5 이상의 제네릭(generic) 메소드 방식 사용해 getBean()의 두 번째 파라미터에 리턴 타입을 주면 지저분한 캐스팅 코드 사용 안 할 수 있음
스프링 기능 사용 시 필요한 라이브러리

1. 스프링 배포판 다운로드
2. 예제의 lib 폴더에서 필요한 파일을 클래스패스에 포함시키기

 

스프링을 적용하긴 했지만 사실 앞에서 만든 DaoFactory를 직접 사용한 것과 기능적으로 다를 바 없음

오히려 DaoFactory를 만들어서 바로 사용한 것보다 좀 더 번거로운 준비 작업과 코드가 필요함

 

스프링을 사용해 IoC를 적용했다고 해서 별로 장점이 없지 않을까 의문이 들 수도 있음

하지만 더 많은 기능이 있음

 

1.5.2. 애플리케이션 컨텍스트의 동작방식

기존에 오브젝트 팩토리를 이용했던 방식과 스프링의 애플리케이션 컨텍스트를 사용한 방식 비교

 

오브젝트 팩토리에 대응되는 것이 스프링의 애플리케이션 컨텍스트

스프링에서는 이 애플리케이션 컨텍스트를 IoC 컨테이너 혹은 간단히 스프링 컨테이너, 빈 팩토리라고 부르기도 함
애플리케이션 컨텍스트

- ApplicationContext 인터페이스 구현
- ApplicationContect는 BeanFactory 인터페이스를 상속
- BeanFactory는 빈 팩토리가 구현
- 따라서 애플리케이션 컨텍스트는 일종의 BeanFactory인 셈

애플리케이션 컨텍스트가 스프링의 가장 대표적인 오브젝트이므로, 애플리케이션 컨텍스트를 스프링이라고 부르기도 함
DaoFactory와 애플리케이션 컨텍스트의 차이점

- DaoFactory
    1) UserDao를 비롯한 DAO 오브젝트 생성 및 DB 생성 오브젝트와의 관계 형성 > 제한적
    2) 직접 오브젝트를 생성하고 관계를 맺어주는 코드가 있음

- 애플리케이션 컨텍스트
    1) 애플리케이션에서 IoC를 적용해 관리할 모든 오브젝트에 대한 생성과 관계설정 담당
    2) 오브젝트 생성정보와 연관관계 정보를 별도의 설정정보를 통해 얻음
        때로는 외부의 오브젝트 팩토리에 작업 위임 후 그 결과를 가져다 사용하기도 함

 

애플리케이션 컨텍스트가 동작하는 방식

  1. @Configuration이 붙은 DaoFactory는 이 애플리케이션 컨텍스트가 활용하는 IoC 설정정보
  2. 내부적으로는 애플리케이션 컨텍스트가 DaoFactory의 userDao() 메소드를 호출해서 오브젝트를 가져온 것을 클라이언트가 getBean()으로 요청할 때 전달해줌
  3. 애플리케이션 컨텍스트는 DaoFactory 클래스를 설정정보로 등록해두고 @Bean이 붙은 메소드의 이름을 가져와 빈 목록을 만듦
  4. 클라이언트가 애플리케이션 컨텍스트의 getBean() 메소드 호출 시 자신의 빈 목록에서 요청한 이름이 있는지 찾고, 있다면 빈을 생성하는 메소드 호출 후 오브젝트를 생성하여 클라이언트에 돌려줌

 

애플리케이션 컨텍스트가 동작하는 방식

 

DaoFactory와 같은 오브젝트 팩토리에서 사용했던 IoC 원리를 그대로 적용하는 데 애플리케이션 컨텍스트를 사용하는 이유는 범용적으로 유연한 방법으로 IoC 기능을 확장하기 위함

 

애플리케이션 컨텍스트 장점 - DaoFactory를 오브젝트 팩토리로 직접 사용했을 때와 비교

1. 클라이언트는 구체적인 팩토리 클래스를 알 필요가 없음
    1) DaoFactory
        - 애플리케이션 발전 시 DaoFactory처럼 IoC를 적용한 오브젝트로 계속 추가될 것
        - 클라이언트가 필요한 오브젝트를 가져오려면 어떤 팩토리 클래스를 사용해야 할지 알아야 함
        - 필요할 때마다 팩토리 오브젝트를 생성해야 함
    2) 애플리케이션 컨텍스트
        - 애플리케이션 컨텍스트를 사용하면 오브젝트 팩토리가 아무리 많아져도 이를 알아야하거나 직접 사용할 필요X
        - 애플리케이션 컨텍스트 사용 시 일관된 방식으로 원하는 오브젝트 불러올 수 있음
        - DaoFactory처럼 자바 코드를 작성하는 대신 XML처럼 단순한 방법을 사용해 애플리케이션 컨텍스트가 사용할 IoC 설정정보를 만들 수도 있음
2. 애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해줌
    - 애플리케이션 컨텍스트의 역할
        1) 오브젝트 생성과 다른 오브젝트와의 관계설정
        2) 오브젝트가 만들어지는 방식, 시점과 전략을 다르게 가져갈 수도 있음
        3) 자동생성, 오브젝트에 대한 후처리, 정보의 조합, 설정방식의 다변화, 인터셉팅 등 오브젝트를 효과적으로 활용할 수 있는 다양한 기능을 제공
        4) 빈이 사용할 수 있는 기반기술 서비스나 외부 시스템과의 연동 등을 컨테이너 차원에서 제공
3. 애플리케이션 컨텍스트는 빈을 검색하는 다양한 방법을 제공함
    1) getBean() > 빈의 이름을 이용해 빈을 찾아줌
    2) 이외에도 타입만으로 빈 검색, 특별한 애노테이션 설정이 되어 있는 빈 검색 가능

 

1.5.3. 스프링 IoC의 용어 정리

빈(Bean)

1. 용어 : 빈 또는 빈 오브젝트라고 부름
2. 의미
    1) 스프링이 IoC 방식으로 관리하는 오브젝트라는 뜻
    2) 관리되는 오브젝트(managed object)라고 부르기도 함
3. 주의할 점
    1) 스프링을 사용하는 애플리케이션에서 만들어지는 모든 오브젝트가 다 빈은 아님
    2) 스프링이 직접 그 생성과 제어를 담당하는 오브젝트만을 빈이라고 부름
빈 팩토리(Bean Factory)

1. 용어 : 빈 팩토리
2. 의미
    1) 스프링의 IoC를 담당하는 핵심 컨테이너
    2) 빈 등록, 생성, 조회, 리턴, 이 외 부가적인 빈 관리 가능 담당
3. 주의할 점
    1) 보통은 빈 팩토리 바로 사용X > 이를 확장한 애플리케이션 컨텍스트 이용
    2) BeanFactory라고 붙여쓰면 빈 팩토리가 구현하고 있는 가장 기본적인 인터페이스의 이름
        (이 인터페이스에 getBean()과 같은 메소드가 정의되어 있음)
애플리케이션 컨텍스트(Application context)

1. 용어 : 빈팩토리와 비교
    1) 빈팩토리 : 빈의 생성과 제어의 관점
    2) 애플리케이션 컨텍스트 : 스프링이 제공하는 애플리케이션 지원 기능을 모두 포함
2. 의미
    1) 빈 팩토리를 확장한 IoC 컨테이너
    2) 빈 등록 및 관리하는 기본적인 기능은 빈 팩토리와 동일
    3) 여기에 스프링이 제공하는 각종 부가 서비스를 추가로 제공
3. 주의할 점
    1) 빈팩토리보다 애플리케이션 컨텍스트를 더 많이 사용
    2) AppicationContext라고 적으면 애플리케이션 컨텍스트가 구현해야 하는 기본 인터페이스를 가리킴
        (ApplicationContext는 BeanFactory를 상속함)
설정정보/설정 메타정보(Configuration Metadata)

1. 용어 : 스프링의 설정정보 혹은 설정 메타정보, 애플리케이션의 형상 정보, 애플리케이션의 전체 그림이 그려진 청사진 등
2. 의미 : 애플리케이션 컨텍스트 또는 빈 팩토리가 IoC를 적용하기 위해 사용하는 메타정보
3. 주의할 점
    1) 스프링의 설정정보는 컨테이너에 어떤 기능을 세팅하거나 조정하는 경우에도 사용
    2) 하지만 위 경우보다는 IoC 컨테이너에 의해 관리되는 애플리케이션 오브젝트를 생성하고 구성할 때 사용됨
컨테이너(Container) 또는 IoC 컨테이너

1) 컨테이너 또는 IoC컨테이너 : IoC 방식으로 빈을 관리한다는 의미에서 애플리케이션 컨텍스트나 빈 팩토리를 부르는 말 > 주로 빈 팩토리의 관점
2) 컨테이너 또는 스프링 컨테이너
    - 애플리케이션 컨텍스트를 가리킴
    - 컨테이너라는 말 자체가 IoC의 개념을 담고 있기 때문에 이름이 긴 애플리케이션 컨텍스트 대신에 스프링 컨테이너라고 부르는 걸 선호하는 사람도 있음 > 애플리케이션 컨텍스트는 그 자체로 ApplicationContext 인터페이스를 구현한 오브젝트를 가리키기도 하는데, 애플리케이션 컨텍스트 오브젝트는 하나의 애플리케이션에서 보통 여러 개가 만들어져 사용됨 > 이를 통틀어서 스프링 컨테이너라고 부를 수 있음
3) 스프링
    - 컨테이너라는 말을 떼고 스프링이라고 부를 때도 스프링 컨테이너를 가리키는 말일 수 있음
    - '스프링에 빈을 등록하고' 라는 말 = '스프링 컨테이너 또는 애플리케이션 컨텍스트에 빈을 등록하고'
스프링 프레임워크

- IoC 컨테이너, 애플리케이션 컨텍스트를 포함해서 스프링이 제공하는 모든 기능을 통틀어 말할 때 주로 사용
- 줄여서 스프링이라고 말하기도 함