스프링 - DI 흐름만 이해하자

김지인·2022년 7월 1일
0
post-thumbnail

이 글에서는 xml, 어노테이션 등을 다루는 법은 안적었습니다.


스프링을 들어가기전에 복습하는 차원에서 꼭 알아야 할 기본 개념을 짚고 넘어가자.
스프링에서는 기본적으로 DI(의존성 주입)을 제공하는데 이 글은 그것이 왜 사용이 되는지에 대한 글이다.

아주 쉽게 이해를 돕기 위해 임의로 국어점수와 영어점수를 더하고(plusLogic)
그 결과값 받아 출력하는 로직(printLogic)을 따로 짜보겠다.

public interface plus {
	int plusResult();
}

public class plusLogic implements plus{
	private int kor = 30;
	private int eng = 40;
	
    @Override
	public int plusResult() {
		return kor+eng;
		
	}
}

국어점수와 영어점수를 더하는 로직

public interface print {
	void printActionLogic();
}
public class printLogic implements print{
	private plus pluslogic;
	
	printLogic() {
		pluslogic = new plusLogic();
		
	}
	@Override
	public void printActionLogic() {
		System.out.printf("plusResult : %d", pluslogic.plusResult());
		
	}
}

plusLogic으로 부터 값을 받아 그 결과를 출력하는 로직


이 두 로직을 보면 'printLogic'에서 'plusLogic'객체를 생성하여 사용하고 있다.

즉 두 클래스는 아주 강하게 결합되어 있다고 볼 수 있다.

그렇다면 이 로직은 어떻게 실행할까?

public class mainLogic {

	public static void main(String[] args) {
		
		
		print printlogic = new printLogic();
		
		printlogic.printActionLogic();

	}

}
출력결과 // plusResult : 70

콘솔창에 띄워주는 로직


이 로직을 보면 'plusLogic''printLogic'안에 담겨져 있기 때문에 'mainLogic'에서는 보이지도 않는다.

??? : "혹시 출력결과를 한글로 '결과 : '이렇게 바꿔주실 수 있나요?"

만약에 로직이 복잡하게 구현된 10000줄짜리면 어떡할건가?
일일이 다 수정해야 할수도 있는 끔찍한 상황일 것이다.
또한 결합되어 있는 다른 클래스들도 다 뜯어봐야 할수도 있다.

울며겨자 먹기로 한글로 출력하는 로직을 새로 구성해보자.

 public class koreaPrintLogic implements print {
	private plus pluslogic;
	
    koreaPrintLogic(){
		pluslogic = new plusLogic();
		
	}
	
	@Override
	public void printActionLogic() {
		System.out.printf("결과 : %d",  pluslogic.plusResult());

	}

}
출력결과 // 결과 : 70

결과를 한글로 출력해주는 로직


동일한 방법으로 새로운 한글로 출력하는 로직을 새로 구성했다.

근데 만약에 'mainLogic'을 수정할 일이 생기고 강한 결합때문에 차례대로 'koreaPrintLogic', 'plusLogic'을 수정해야 한다고 가정하자. 그리고 그 수정해야 하는 줄이 10000줄이라고 생각하자.

우여곡절 끝에 수정을 성공했다고 하자.

그런데 어느날...

??? : "혹시 저번 때처럼 'plusResult :' 로 출력해주실 수 있나요?"

(날 죽여줘..)

만약에 저 로직들이 10000줄로 구성되어있다면 다시 로직을 짜는게 빠를 것이다.
왜냐하면 이미 'plusLogic''koreaPrintLogic'에 맞게 수정되었기 때문이다.

그렇다면 각 클래스 마다 결합력을 낮춰서 부품처럼 사용하는 방법은 없을까?

가능하다!

public class printLogic implements print{
	private plus pluslogic;
	
    /*
    printLogic() {
		pluslogic = new plusLogic();
		
	}
    */
	printLogic(plus pluslogic) {
		this.pluslogic = pluslogic;
		
	}
	
	public void printActionLogic() {
		System.out.printf("plusResult : %d", pluslogic.plusResult());
		
	}
} 
-------------------------------------------------------------------------------------
public class koreaPrintLogic implements print {
	private plus pluslogic;
	
    /*
     koreaPrintLogic() {
		pluslogic = new plusLogic();
		
	}
    */
    
	public koreaPrintLogic(plus pluslogic){ 
		this.pluslogic = pluslogic;
		
	}
	
	@Override
	public void printActionLogic() {
		System.out.printf("결과 : %d",  pluslogic.plusResult());

	}

}

수정한 출력 로직

public class mainLogic {

	public static void main(String[] args) {
		
		plus pluslogic = new plusLogic();
		print printlogic = new printLogic(pluslogic);
		print koreaprintlogic = new koreaPrintLogic(pluslogic);
		
		printlogic.printActionLogic();
		System.out.println();
		koreaprintlogic.printActionLogic();
	}

//출력결과 
plusResult : 70
결과 : 70

이렇게 되면 원하는 대로 객체를 생성하여 출력이 가능해진다.

근데 뭐가 좋은거야?

  1. 클래스들 사이의 결합이 느슨해 짐에 따라 자유롭게 변경이 가능하다.

  2. 그리고 각자 고유의 캡슐화 된 클래스이므로 유지보수가 용이하다.(물론 이 예제에서는 각 클래스마다 물고 늘어지는 로직을 구현하지 않았다.)


근데 스프링에서는 이렇게 객체를 생성하고 소멸, 의존관계를 개발자가 직접하는 것이 아닌 XML이나 어노테이션을 통해 스프링 프레임워크가 도와준다. 그것을 DI라 한다.

profile
에러가 세상에서 제일 좋아

0개의 댓글