일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- spring
- gradle
- Java
- Stack
- Real MySQL
- 자바 ORM 표준 JPA 프로그래밍
- list
- 쿠버네티스
- 백준
- K8s
- 스프링
- 이스티오
- thread
- JPA
- jvm
- 스트림
- GC
- Stream
- SpringBoot
- 토비의 스프링 정리
- 자바
- Kotlin
- Collection
- OS
- redis
- MSA
- IntellJ
- 보조스트림
- mysql
- 토비의 스프링
- Today
- Total
인생을 코딩하다.
[Spring] IOC와 DI 본문
Spring 프레임워크는 자바 엔터프라이즈 애플리케이션을 개발하기 위한 프레임워크다
즉, 기업들에게 애플리케이션을 보다 쉽게 개발할 수 있도록 서비스를 제공한다
어떻게?
데이터베이스 연동이나 다른 시스템과의 연동같은 복잡한 로직을 분리시켜개발자가 비즈니스 로직 에만 신경쓰도록
만들어주는 핵심 기능이 IOC와 DI다.
IOC (Inversion of Control)
- 제어의 역전
- 개발자가 아닌 프로그램이 코드의 흐름을 제어하는 것
- 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것을 제어의 역전(IoC)이라 한다.
public class HyungIl{
private Child child;
public HyungIl(){
this.child = new Hosick();
}
public void carry(){
this.child.study();
}
}
interface Child{
void study();
}
class Hosick implements Child{
@Override
void study(){
System.out.println("찡찡대기");
}
}
class Hosick implements Child{
@Override
void study(){
System.out.println("주말이니 쉬러가기");
}
}
위 코드를 보면 Hyungil 클래스는 본인의 Child 필드를 Hosick 클래스로 결정하고 있다
이는 본인의 비즈니스 로직을 작성할 뿐만 아니라 아닌 필드의 인스턴스까지 결정과 생성하고 있음을 알 수 있다
이렇게 되면 무엇이 문제인가?
예를 들어
Hosick 클래스 생성자의 파라미터가 필요하게 되었다고 가정하자 ,그러면 Hyungil 클래스의 생성자도 바꾸어 주어야 한다. 만약 Hyungil 과 같은 클래스가 100개라고 생각해보자. 100개의 클래스를 모두 바꾸어야 한다. 이러한 사실들로 볼때 그 시스템은 클래스 간의 결합도가 높다. 따라서 이러한 결합도를 줄이고 SOLID의 SRP(Single Responsibility Principle즉, 단일 책임 원칙을 지키고자 나온 개념이 IOC 이다. IOC 개념은 Spring에서만 국한되지 않는다. IOC 는 제 3자에게 제어권을 주면서 자신의 비즈니스 로직에만 집중하는 개념이다. 따라서 위 예제를 고쳐보면
public class AppConfig{
public Hyungil work(){
return new Hyungil();
}
public Hosick smoke(){
return new Hosick();
}
public Minsub gaepodong(){
return new Minsub();
}
}
public class Hyungil{
private Child child;
public Hyungil{
this.child = new AppConfig().smoke();
}
//이하 동일
}
Hyungil 클래스의 child 필드의 인스턴스 생성을 AppConfig 클래스에 맡김으로써 만약 Hosick 클래스가 바뀌더라도 Hyungil 클래스는 신경을 안써도 된다. AppConfig 클래스같은 역할을 하는 클래스를 컨테이너라 부를 수 있다.
DI (Dependency Injection)
-
IOC를 구현하는 방법 중 하나
-
의존성 주입
-
클래스들간 의존관계를 설정한 정보를 토대로 컨테이너가 자동으로 연결하는 것
-
지켜야할 조건
- 코드에 의존 관계가 드러나지 않는다. 그렇기 위해 인터페이스에 의존한다
- 의존관계는 제 3자에 의해 결정되어야 한다.
- 의존관계는 사용할 인스턴스의 참조는 제 3자로부터 받는다.
public class Hyungil{
private Child child;
public Hyungil(){
this.child = new Hosick();
}
}
interface Child{
void study();
}
class Hosick implements Child{
@Override
void study(){
}
}
앞서 나왔던 예제에서 Hyungil 클래스는 child 필드의 인스턴스를 Hosick 인스턴스로 결정하는 것이 보임으로써 DI가 적용이 안된 것을 알 수 있다.
public class Hyungil{
private Child child;
public Hyungil(Child child){
this.child = child;
}
}
제 3자로부터 child 필드의 인스턴스를 받아와서 적용하기 때문에 제 3자가 인스턴스를 결정하고 제공함을 알 수 있다.
Spring 에서는 Component 어노테이션을 붙여주면 Spring의 컨테이너가 알아서 인스턴스를 생성해주고 클래스 사이를 자동으로 연결해준다.때문에 Spring 컨테이너가 DI 개념의 제 3자 역할을 한다. 이렇게 Spring에서 관리하는 클래스들을 Spring에선 Bean 이라고 부르며 개발자가 설정한 이 Bean 들을 관리해주는 두 가지 컨테이너는
- BeanFactory : IoC/DI 기본 기능
- ApplicationContext : BeanFactory 모든 기능 포함, 일반적으로 추천
DI Container 를 사용함으로써 코드 작성 시 의존관계가 나타나지 않고, 결합도가 낮은 코드를 만들 수 있게 해준다.
따라서 변경과 확장을 자유롭게 할 수 있기 때문에 시스템이 유연해진다.
참고
[Spring] Spring의 정의와 기본 개념
Spring IoC/DI 컨테이너
[Spring] Spring의 핵심 기술 IoC/DI
IoC, DI란 무엇일까
'Spring' 카테고리의 다른 글
[Spring] Dispatcher Servlet이란?, Servlet & Spring Web MVC (0) | 2021.02.17 |
---|---|
[Spring] AOP(Aspect-Oriented Programming) (0) | 2021.02.10 |
[Spring] 레이어 구조에 관한 고찰 (0) | 2020.12.27 |
[Spring] 스프링 테스트 전략 (0) | 2020.12.27 |
[Spring] RestTemplate (0) | 2020.12.17 |