BackEnd/Spring & Springboot Study

[토비의 스프링] 1장 정리 [IoC와 DI]

 

스프링과 그 기본 개념인 IoC와 DI에 대해 간단하게 다뤄보겠습니다.

 

1. 그래서 스프링 프레임 워크가 뭔데?

자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크
엔터프라이즈급 애플리케이션을 개발하기 위한 모든 기능을 종합적으로 제공하는 경량화된 솔루션입니다.

엔터프라이즈급 개발이란 뜻대로만 풀이하면 기업을 대상으로 하는 개발이라는 말입니다.
즉, 대규모 데이터 처리와 트랜잭션이 동시에 여러 사용자로 부터 행해지는 매우 큰 규모의 환경을
엔터프라이즈 환경이라 일컫습니다.

Spirng Framework는 경량 컨테이너로 자바 객체를 담고 직접 관리합니다.
객체의 생성 및 소멸 그리고 라이프 사이클을 관리하며 언제든 Spring 컨테이너로 부터 필요한 객체를 가져와 사용할 수 있습니다. 이는 Spirng이 IoC 기반의 Framework임을 의미합니다.

 

2. IoC기반? IoC는 뭐지?

IOC는 Inversion of Control의 약자로 말 그대로 제어의 역전입니다. 그럼 제어의 역전이란 무엇일까요?

일반적으로 지금까지 프로그램은
객체 결정 및 생성 -> 의존성 객체 생성 -> 객채 내의 메소드 호출 하는 작업을 반복했습니다.
이는 각 객체들이 프로그램의 흐름을 결정하고 각 객체를 구성하는 작업에 직접적으로 참여한 것입니다.
즉, 모든 작업을 사용자가 제어하는 구조인 것입니다.

하지만 IOC에서는 이 흐름의 구조를 바꿉니다. IOC에서의 객체는 자기가 사용할 객체를 선택하거나 생성하지 않는다.
또한 자신이 어디서 만들어지고 어떻게 사용되는지 또한 모릅니다.
자신의 모든 권한을 다른 대상에 위임함으로 써 제어권한을 위임받은 특별한 객체에 의해 결정되고 만들어집니다.
즉, 제어의 흐름을 사용자가 컨트롤 하지 않고 위임한 특별한 객체에 모든 것을 맡기는 것입니다.

IOC란 기존 사용자가 모든 작업을 제어하던 것을 특별한 객체에 모든 것을 위임하여 객체의 생성부터 생명주기 등 모든 객체에 대한 제어권이 넘어 간 것을 IOC, 제어의 역전 이라고 합니다.

 

1. IoC 변경 전 직접 제어하는 코드

public UserDao(ConnectionMaker connectionMaker) {
		this.connectionMaker = connectionMaker;
}
public class UserDaoTest {
	public static void main(String[] args) throws ClassNotFoundException, SQLException{
		ConnectionMaker connectionMaker = new DConnectionMaker();
		UserDao dao = new UserDao(connectionMaker);
	}
}

객체의 제어를 직접 다룸

2. IoC로 제어의 권한을 간접적으로 변경한 코드

public class DaoFactory {
	public UserDao userDao() {
		ConnectionMaker connectionMaker = new DConnectionMaker();
		UserDao userDao = new UserDao(connectionMaker);
		return userDao;
	}
}
public class UserDaoTest {
	public static void main(String[] args) throws ClassNotFoundException, SQLException{
		UserDao dao = new DaoFactory().userDao();
		...
	}
}

객체의 제어를 간접적으로(Factory가) 다룸

 

 

3. 스프링에서 IoC하는 방법은 뭔가 다르다던데?

 

 

DI를 다루기 전 알아야 하는 용어

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


빈(bean)이란?
스프링에서 스프링이 제어권을 가지고 직접 관계를 부여하는 오브젝트
자바빈 또는 엔터프라이즈 자바빈(EJB)에서 말하는 빈과 비슷한 오브젝트 단위의 애플리케이션 컴포넌트
스프링 컨테이너가 생성과 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트

빈 팩토리(bean factory)란?
빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트
보통 빈 팩토리를 확장한 애플리케이션 컨텍스트(IoC 방식에 따라 만들어진 빈 팩토리)를 사용한다.
빈을 생성하고 관계를 설정하는 IoC의 기본 기능에 초점

애플리케이션 컨텍스트(Application context)란?
빈 팩토리와 동일, 애플리케이션 전반에 걸쳐 모든 구성요소의 제어 작업을 담당하는 IoC엔진이란 의미가 부각됌
별도의 정보를 참고해 빈(object)의 생성, 관계설정 등의
제어 작업을 총괄별도의 설정정보를 담고 있는 무엇인가를 가져와 이를 활용하는 범용적인 IoC 엔진

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

@Configuration
스프링이 빈 팩토리를 오브젝트 설정을 담당하는 클래스라고 인식하게 하는 어노테이션수동으로 스프링 컨테이너에 빈을 등록하기 위해 사용됌

@Bean

오브젝트 생성을 담당하는 IoC용 메소드메소드 이름으로 빈 이름이 결정되므로 중복된 빈 이름이 존재하지 않도록 주의
개발자가 직접 제어가 불가능한 라이브러리를 활용시 사용유지보수성을 높이기 위해 애플리케이션 전범위적으로 사용되는 클래스를 등록시 사용
다형성을 활용하여 여러 구현체를 등록해주어야 할때 사용

Example Code

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

 

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

4. 그래서 IoC랑 DI의 차이점이 뭔데?

IoC는 DI를 내포하는 개념 (DI ⊂ IoC)
의존관계 주입이란 다음과 같은 세 가지 조건을 충족하는 작업을 말한다.

1. 클래스 모델이나 코드에는 런타임 시점의 의존관계가 드러나지 않는다.
그러기 위해서는 인터페이스에만 의존하고 있어야 한다.
2. 런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제3의 존재가 결정한다.
3. 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공(주입)해줌으로써 만들어진다.

런타임시 의존 관계가 미리 결정되어 있는 코드

public UserDao() {
	connectionMaker = new DConnectionMaker();
}

클래스/코드 레벨의 의존관계

DI 컨테이너가 클래스의 오브젝트를 만들고 생성자의 파라미터로 오브젝트의 레퍼런스를 전달해 주는 코드

 

public Class UserDao {
	private ConnectionMaker connectionMaker;
    
    public UserDao(ConnectionMaker connectionMaker) {
    	this.connectionMaker = connectionMaker;
    }
}

 

5. DI의 여러가지 방법들

 

DaoFactory를 이용한 코드

public UserDao() {
	DaoFactory daoFactory = new DaoFactory();
    this.connectionMaker = daoFactory.connectionMaker();
}

의존관계 검색(DL)을 이용하는 UserDao 생성자 코드

public UserDao() {
	AnnotationConfigApplicationContext context =
    	new AnnotationConfigApplicationContext(DaoFactory.class);
    this.connectionMaker = context.getBean("ConnectionMaker", ConnectionMaker.class);
}


의존 주입의 3가지 방법

생성자 주입(Constructor Injection)

public class A {
    private B b;
    
    public A(B b) {
        this.b = b;
    }
}

Setter 주입(Setter Injection)

public class A {
    private B b;
    
    public void setB(B b) {
        this.b = b;
    }
}

 

인터페이스 주입(Interface Injection)

public interface BInjection {
    void inject(B b);
}

public A implements BInjection {
    private B b;
    
    @Override
    public void inject(B b) {
        this.b = b;
    }
}

 

 

 

용어 정리

 

객체지향 설계 원칙(SOLID)
SRP(The Single Responsibility Principle): 단일 책임 원칙
- 한 클래스는 하나의 책임만 가져야 한다.
OCP(The Open CLosed Principle):개방 폐쇄 원칙
- 소프트웨어는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
LSP(The Liskov Substitution Principle):리스코프 치환 원칙
- 프로그램 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다. 
ISP(The Interface Segregation Principle): 인터페이스 분리 원칙
- 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
DIP(The Dependency Inversion Principle): 의존관계 역전 원칙
- 프로그래머는 "추상화에 의존해야지, 구체화에 의존하면 안된다." [의존성 주입은 이 원칙을 따르는 방법 중 하나]


https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
 
높은 응집도와 낮은 결합도 ( high coherence and low coupling)
높은 응집도모듈에 포함된 내부 요소들이 하나의 책임/목적을 위해 응집됨즉 모듈 내부의 기능적인 응집도가 크다변화가 일어날시 변경 대상과 범위가 명확해 짐낮은 결합도'하나의 오브젝트가 변경이 일어날 때에 관계를 맺고 있는 다른 오브젝트에 변화를 요구하는 정도'변화에 대응하는 속도가 높아지고, 구성이 깔끔하며, 확장에 용이

전략 패턴 (Strategy Pattern)

자신의 기능 맥락(context)에서, 필요에 따라 변경이 필요한 알고리즘을 인터페이스를 통해 통째로 외부로 분리시키고, 이를 구현한 구체적인 알고리즘 클래스를 필요에 따라서 바꿔서 사용할 수 있게 하는 디자인 패턴
여기서 알고리즘이란 독립적인 책임으로 분리가 가능한 기능을 뜻한다. 즉 대체 가능한 전략에서 전략패턴 이라는 이름이다.

 

빈(Bean)
스프링이 IoC방식으로 관리하는 오브젝트
스 프링이 직접 그 생성과 제어를 담당하는 오브젝트

빈 팩토리(bean factory)
스프링의 IoC를 담당하는 핵심 컨테이너
빈의 등록, 생성, 조회, 반환 및 관리 기능
보통 이를 확장시킨 애플리케이션 컨텍스트를 이용
BeanFactory라 붙여쓰면 빈 팩토리가 구현하고 있는 가장 기본적인 인터페이스의 이름
이 인터페이스에 getBean()과 같은 메소드가 정의되어 있음

애플리케이션 컨텍스트(application context)
빈 팩토리를 확장한 IoC 컨테이너
빈의 생성과 제어를 담당하는 빈 팩토리를 상속한다.
추가로 스프링이 제공하는 애플리케이션 지원 기능을 포함
ApplicationContext라고 적으면 애플리케이션 컨텍스트가 구현해야 하는 기본 인터페이스를 가리킴

설정정보 / 설정 메타정보(configuration metadata)
애플리케이션 컨텍스트 또는 빈 팩토리가 IoC를 적용하기 위해 사용하는 메타정보
컨테이너에 어떤 기능을 세팅하거나 조정하는 경우 사용
IoC 컨테이너에 의해 관리되는 애플리케이션 오브젝트를 생성하고 구성할 때 사용
애플리케이션 형상정보 또는 애플리케이션의 전체 그림이 그려진 청사진(blueprints)이라고도 한다.

컨테이너(container) 또는 IoC 컨테이너
IoC 방식으로 빈을 관리한다는 의미에서 애플리케이션 컨텍스트나 빈 팩토리를 컨테이너 또는 IoC 컨테이너라 함IoC 컨테이너는 주로 빈 팩토리 관점
그냥 컨테이너 또는 스프링 컨테이너라 할 때는 애플리케이션 컨텍스트를 가리킴
애플리케이션 컨텍스트 오브젝트는 하나의 애플리케이션에서 여러개 만들어 사용, 통틀어 스프링 컨테이너라 부름

스프링 프레임워크
IoC 컨테이너, 애플리케이션 컨텍스트를 포함해 스프링이 제공하는 모든 기능을 통틀어 말할 때 주로 사용

 


더 자세한 내용은 아래 포스팅에서 다뤘습니다.

- Link


아직 이해하는 중이라 부족한 점이 많은 글임을 양해 부탁드립니다.
조언 주시면 감사히 적용해보겠습니다.


References by

https://khj93.tistory.com/entry/Spring-Spring-Framework%EB%9E%80-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%ED%95%B5%EC%8B%AC-%EC%A0%95%EB%A6%AC

 

[Spring] Spring Framework란? 기본 개념 핵심 정리

Spring Framework란? 자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크로서 엔터프라이즈급 애플리케이션을 개발하기 위한 모든 기능을 종합적으로 제공하는 경량화된 솔루션입니다. 엔터프

khj93.tistory.com

https://velog.io/@ohzzi/Spring-DIIoC-IoC-DI-%EA%B7%B8%EA%B2%8C-%EB%AD%94%EB%8D%B0

 

[Spring DI/IoC] IoC? DI? 그게 뭔데?

스프링을 공부하다 보면 꼭 나오는 이야기가 있다. 스프링은 IoC 컨테이너로 빈을 관리한다. 스프링은 DI를 사용한다 .DI 방법에는 생성자 주입, setter 주입, 필드 주입 등이 있다.... 아니 근데 대체

velog.io

https://sangw0804.github.io/java/spring/8.%EC%8A%A4%ED%94%84%EB%A7%81%EC%9D%B4%EB%9E%80_%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80/

 

8.스프링이란_무엇인가.md

스프링이란 무엇인가

sangw0804.github.io

https://gunju-ko.github.io/toby-spring/2019/03/25/IoC-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-DI.html

 

토비의 스프링 - IoC 컨테이너와 DI

이 글은 “토비의 스프링” 책 내용을 정리한 글입니다. 만약 저작권 관련 문제가 있다면 “gunjuko92@gmail.com”로 메일을 보내주시면, 바로 삭제하도록 하겠습니다. 토비의 스프링 - IoC 컨테이너와

gunju-ko.github.io

https://beforb.tistory.com/38

 

[Spring] IoC와 DI - 1. 오브젝트와 의존관계(토비의 스프링)

목차 스프링이란? 1.1. 스프링의 핵심 프로그래밍 모델 오브젝트와 의존 관계 2.1. 상속을 통한 확장 2.2. 오브젝트 2.3. 관계설정 책임의 분리 용어 정리 포스팅을 시작하며.. SSAFY에서 2학기 프로젝

beforb.tistory.com