Spring

토비의 스프링 - IoC, Application Context, 의존 관계

컨트롤디 2024. 7. 3. 23:59

* 용어

스프링 프레임 워크

IoC 컨테이너를 포함해서 스프링이 제공하는 모든 기능을 통틀어 말할 때 주로 사용한다.

 

 

IoC 컨테이너

애플리케이션 컨텍스트, 빈 팩토리랑 같은 의미로 표현된다.

 

 

팩토리

객체의 생성 방법을 결정하고, 그렇게 만들어진 객체를 돌려주는 역할을 하는 오브젝트

 

public class Factory {
	
    public UserDto getUserDto(){
    
        DbConnector connect = new DbConnector();

        UserDto user = new UserDto(connect);
        return userDto();
    }
}

 

Factory의 getUserDto를 호출하면 디비 커넥션 설정을 가져오고, user 오브젝트를 돌려주는 역할을 해준다.

 

이를 통해 클라이언트에서는 팩토리 클래스를 활용하면 디비 커넥션, 오브젝트 초기화 부분을 신경쓰지 않고 호출만 하면 된다.

 

 

 

이 팩토리의 역할을 어떻게 정의할 수 있을까?

애플리케이션을 구성하는 핵심적인 로직들의 관계를 정의하는 책임을 맡는 것이다.

즉, 컴포넌트의 구조와 관계를 정의하는 설계도와 같은 역할을 한다고 할 수 있다.

그래서 오브젝트가 어떤 오브젝트를 사용하는지를 정의하는 코드가 주로 들어간다.

 

 

 

제어의 역전이란?

모든 종류의 작업을 사용하는 쪽에서 제어하는 것이 아닌,

오브젝트가 자신이 사용할 오브젝트를 스스로 선택하지 않고 팩토리와 같이 다른 오브젝트에게 모든 제어 권한을 위임하는 것을 의미한다.

 

예를 들어, 프로젝트의 시작을 담당하는 main 메소드는 엔트리 포인트를 제외하면 모든 오브젝트들에게 제어 권한을 위임한다.

 

대표적인 기술로 프레임워크가 있다.

프레임워크는 라이브러리들을 활용해 애플리케이션 흐름을 제어하도록 만들어진 반제품이라고 볼 수 있다.

이는 단지, 동작 중에 필요한 작업에 라이브러리를 사용하는 것일 뿐이다.

 

그리고 개발자는 그 프레임워크가 짜놓은 틀 안에서 애플리케이션 코드를 작성한다.

그러면 개발자는 코드를 작성할 뿐, 실제 애플리케이션을 직접 제어하는 것은 프레임워크가 되는 것이다.

 

 

 

Bean의 등장

팩토리를 이러한 원리를 가지고 스프링에 적용하면 어떻게 될까?

 

스프링에서는 스프링의 제어권을 가지고 직접 관계를 만들어 부여하는 오브젝트Bean 이라고 부른다.

이는 스프링 컨테이너가 생성, 관계 설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트이다.

 

그리고 이러한 빈의 생성과 관계 설정과 같은 제어를 담당하는 IoC 오브젝트를 빈 팩토리라고 부른다.

빈 팩토리를 활용한 대표적인 오브젝트로 애플리케이션 컨텍스트(ApplicationContext) 가 있다.

 

 

 

Application Context

이 오브젝트는 애플리케이션 전반에 걸쳐 모든 구성 요소의 제어 작업을 담당하는 IoC 엔진이라고 볼 수 있다.

 

예를 들어,

UserDto 와 DbConnection이 있을 때, UserDto와 DbConnection의 관계 설정을 어떻게 할 지를 제어한다.

하지만 애플리케이션 컨텍스트에서 이 정보를 직접 담고 있진 않다.

대신 설정 정보를 담고 있는 Config 클래스를 불러와서 활용하는 역할을 해준다.

 

이렇게 그 자체로는 애플리케이션 로직을 담당하고 있진 않지만 IoC 방식을 이용해

애플리케이션  컴포넌트를 생성하고, 사용할 관계를 맺어주는 책임을 담당하는 설계도와 같은 역할을 한다.

 

* 스프링에서는 이러한 설정 정보를 담당하는 애노테이션을 @Configuration 으로 표시한다.

@Configuration
public class dbConfig {
	//
    @Bean
    public DbConnection connection(){
    	return new DbConnection();
    }
    
 }

 

public class test(){
	//
    main(){
    	ApplicationContext context = new ApplicationContext(DbConfig.class);
    }
}

 

 

애플리케이션 컨텍스트의 장점

1. 클라이언트는 팩토리의 클래스를 알 필요가 없다.

클라이언트가 오브젝트를 가져올 때마다 팩토리 오브젝트를 생성하는 번거러움을 덜어준다.

그리고 아무리 팩토리가 많아져도 이를 알거나 직접 사용할 필요가 없다.

애플리케이션 컨텍스트가 알아서 가져와 준다.

 

 

2. 종합 IoC 서비스를 제공한다.

위와 같은 방식 외에도 오브젝트가 생성되는 방식, 시점, 전략을 다양하게 가져갈 수 있다.

 

 

3. 타입만으로 빈을 편리하게 검색할 수 있는 방법을 제공한다.

 

 

의존관계 주입

IoC는 스프링에서 아주 폭넓게 사용 되는 용어이다.

단순 서블릿 컨테이너인지, IoC 개념이 적용된 템플릿 메소드 패턴을 의미하는지, IoC 특징을 지닌 기술을 의미하는지 알 수 없다.

그래서 의존 관계 주입(DI) 이라는 명확한 이름을 사용하기 시작했다.

 

DI는 오브젝트 레퍼런스를 외부로부터 참조받고 이를 통해 다른 오브젝트와 의존관계가 만들어지는 것이 핵심이다.

 

 

의존관계

의존 관계란 누가 누구에게 의존하는 관계에 있다는 식이어야 한다. 즉, 방향성이 있다.

즉 "A가 B에 의존하고 있다" 라는 것은 "B가 무언가를 하면 A가 영향을 미친다" 라는 의미이다.

 

런타임 의존관계

런타임 시에 의존관계를 맺게 되는 특정 오브젝트를 의미한다.

 

의존 관계 주입의 세가지 조건

1. 클래스나 코드 속에는 런타임 시점의 의존관계가 드러나지 않는다. (인터페이스에만 의존해야 한다)

2. 런타임 시점의 의존관계컨테이너, 팩토리 같은 제3의 존재가 결정한다.

3. 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공해줌으로써 만들어진다.