A가 B를 사용하는 것 "의존성"
의존성이란, A가 B를 사용할 때, A가 B에 의존성을 가진다고 합니다. Person 이라는 클래스가 Knife라는 클래스를 사용해서 Apple을 베는 것을 코드로 표현하면, 이렇게 표현할 수 있겠죠.
// Person
public class Person {
Knife knife = new Knife();
public void cut(Object something){
knife.cut(something);
}
}
// Knife
public class Knife {
public void cut(Object something) {
System.out.println(something + " 을 잘랐습니다");
}
}
// Apple
public class Apple {
@Override
public void toString(){
System.out.println("사과");
}
}
// 메인메소드
public void main(String[] args){
Person juni = new Pserson();
Apple apple = new Apple();
juni.cut(apple);
}
Person이 knife를 사용하기 위해, 생성자를 통해 나이프를 만들고 knife.cut() 메소드를 사용하는 것을 볼 수 있습니다. 이 때 Person이 knife를 생성하지 못하면 cut메소드를 사용할 수 없습니다. 이를 Person이 knife에 의존성을 갖는다. 라고 합니다.
5센트 짜리 개념의 25달러 짜리 용어 "의존성 주입" by James Shore
의존성 주입(DI : dependency Injection) 은 용어가 거창하지만, 사실 가지고 있는 의미는 단순합니다. 의존성을 직접 생성하지 않고, 객체 밖에서 의존성을 쥐어준다는 뜻입니다. 아까의 코드를 예로 들면, Person안에서 new Knife하지 않고, 다른 곳에서 new한 다음에 Person에게 준다는 것이죠.
// Person
public class Person {
Knife knife;
public void setKnife(Knife knife){
this.knife = knife;
}
...
}
// 메인메소드
public void main(String[] args){
Person juni = new Pserson();
Knife knife = new Knife();
juni.setKnife(knife);
Apple apple = new Apple();
juni.cut(apple);
}
이제, Person 객체는 knife를 직접 생성하지 않고, 쥐어주는 knife를 사용해야만 합니다. knife를 바꿀 때 person의 소스코드를 바꿀 필요가 없죠. 이제 person의 소스코드를 들여다 보지 않고도 메인메소드에서 칼을 선택해서 쥐어줄 수 있습니다. Person과 Knife의 결합도가 낮아진 것입니다.
만약 person이 knife를 주입받지 못하면 어떻게 될까요?
// 메인메소드
public void main(String[] args){
Person juni = new Pserson();
Knife knife = new Knife();
// juni.setKnife(knife);
Apple apple = new Apple();
juni.cut(apple);
}
setKnife 코드를 주석 처리했습니다. Person이 Knife를 주입받지 못하면, cut메소드를 실행할 때, knife가 없어서 에러가 발생하게 됩니다. 해결책으로, Person이 Knife가 없으면 생성조차 될 수 없도록 수정했습니다. 생성자를 통해, 객체가 사용할 의존성을 갖춰야만 생성이 가능하도록 한 것이죠.
// Person
public class Person {
Knife knife;
Person(Knife knife) {
this.knife = knife;
}
...
}
// 메인메소드
public void main(String[] args){
Knife knife = new Knife();
Person juni = new Pserson(knife);
Apple apple = new Apple();
juni.cut(apple);
}
이제 person은 knife 가 없으면 생성조차 할 수 없고, 적어도 person의 cut메소드를 실행할 때 knife가 없어서 에러가 발생할 일은 없어졌습니다. 이 방법을 추가로 코딩을 하게 되었는데, 몇가지 아쉬운 점들이 보였습니다.
- Person의 cut메소드가 에러가 나면, Person이 문제인지, knife가 문제인지 다 찾아봐야하는 테스트 문제와,
- Person의 Knife는 항상 같은 기능을 하는데, 여러 쓰레드에서 사용할 때마다 중복되는 클래스를 계속해서 생성하는 메모리 낭비 문제..
- 문제들을 다 해결한 코드를 모든 애플리케이션에 적용하니 코드가 장황해지는 문제..
이런 문제들이 발생했습니다.
이런 여러가지 문제를 해결하기 위해 IoC컨테이너를 만들었습니다.
"너가 사용할 의존성 내가 줄게" by. IoC컨테이너
스프링을 사용하면, 의존성 주입이 필요한 객체를 new로 만들지 않고, 스프링이 객체를 만들어주면서, 만들 때 의존성도 다 주입한 완제품으로 만들어주게 되었습니다. 이제 개발자들은 의도한 대로 만들어진 객체를 사용해서 비즈니스 로직에 집중할 수 있게 되었습니다.
스프링이 만들어 주는 객체는 빈(Bean) 이라고 이름 지었습니다.
이 빈들은 개발자가 new로 만들거나, 의존성을 설정하지 않고, 스프링이 만들고 관리해 주기 때문에 "제어가 역전 됐다" 는 의미로 제어의 역전 (IoC:Inversion of Control) 이라는 용어를 만들었고, 이 빈들을 관리해주는 역할을 하는 것을 IoC컨테이너 라고 부르기로 했습니다.
'성동스터디 (2021.09.09 ~ ing) > Spring' 카테고리의 다른 글
[Spring][이클립스] DevTools 동작 안할 때 (0) | 2021.12.29 |
---|---|
[Spring][이클립스] 메이븐 프로젝트 의존성이 안들어올 때 (0) | 2021.12.29 |
[Spring] @RequestBody, @ModelAttribute, BindingResult (0) | 2021.12.28 |
[Spring][Thymeleaf] background-image 사용하기 (0) | 2021.12.28 |
[Spring] 페이징 글번호 끝에서 부터 표시하기 (1) | 2021.12.24 |
댓글