다른건 몰라도 오늘 IoC랑 DI는 완벽히 알고 가본다..내가 이거 어띃게든 알고간다...
강의에서도 이부분이 젤 많이 듣게 되고 가장많이 나온다고 하는데 뭔지 알아야할꺼아냐!!!!
흠...생소하군....직역:제어의 역전...?
이게 뭔말이냐면 프로그램이 흘러가는걸 직접적으로 제어하는게 아니라 외부에서 시비걸듯이 건드려서 제어하는것을 말한다고 한다.
내가 본 자료에서는 할리우드 원칙
을 이용해 설명해주고 있다.
오디션에 떨어진 배우에게 영화사가 Don't call us. We'll call you." 요딴식으로 말한거를 예를 들어서 이야기하는데
말 그대로 배우들(객체)에게 영화사에서 필요하면 연락할테니 먼저 연락하지 말라는 뜻이다...
(저런...싹바가지없는...)
프레임워크 컨테이너가 생성하고 생명주기를 관리해주는거긴해...
여하튼 이러한 예제를 활용하여 설명을 해주는데 주도권을 잃고 불러주기만을 기다린다는 뜻이긴 한데...
아직 사실 완전히 감이 잡히진 않잖아?
조금만 더 뜯어 보자고 이 개념은 어찌되었든 프레임워크를 이용하는데 쓰이는 개념이니 원래는 어떻게 했는지 보기위해서 예전에 쓰던 방식을 살펴보자.
원래는 객체의 생성, 초기화, 소멸, 메서드 호출 등 모든 일을 클라이언트 구현 객체가 직접 관리해왔다.
또한 다른 사람이 작성한 외부 코드(라이브러리)를 호출하더라도 해당 코드의 호출 시점 역시 직접 관리하게 되겠지 당연히?
그러면 이제 스프링은 한번 봐보자고? Controller, Service 같은 객체들의 동작을 우리가 직접 구현해야해서 그것을 구현해두면 그것들이 어느 시점에 호출될 지는 신경쓰지 않는다.프레임워크가 요구하는대로 객체를 생성하면, 프레임워크가 해당 객체들을 가져다가 생성하고, 메서드를 호출하고, 소멸시키는 일만 하는거지!!!!!!!!
그럼 이제 IoC컨테이너가 뭔지 슬쩍 봐보자고?스프링에서의 IoC 컨테이너란 곧 ApplicationContext interface를 의미한다 그냥 의존 관계 유지 시켜주는 역할이라고 보면 될거같아... 너무 복잡하자나...
결국은 인터페이스를 활용해서 결합도를 낮추고자 하는 것이지 뭐...하나 삑나서 다 뜯을꺼야? 아니잖아?
적당히 슬쩍슬쩍 해주는게 좋고 관리도 좋으니까 이런거 쓰자 이말이야~~~다음으로 넘어가보자고
이것도 생소하다 의존성 주입이라는데... IoC와 DI(Dependency Injection: 의존성 주입)을 헷갈려하거나, 동일시하고는 한다고 한다....뭔소리야?즉 IoC와는 하등 상관이 없는 개념
이라는 말을 어렵게 해둔거지??
다들 코드로 설명을 하니 코드로 봐보자고?'주입'이란, '외부에서'라는 의미를 내포하고있으니 학생 졸지말고 따라오도록
예제코드!!!!!!
public class Car {
Tire tire;
public Car() {
tire = new KoreaTire();
tire = new NorthKoreaTire();
}
Tire는 인터페이스이며, 이를 구현하는 KoreaTire와 NorthKoreaTire가 있다.
위의 코드는 Tire의 구현체 중 어떤 것에 의존할지 Car가 직접 결정하고 있는데 이건 유연성이 떨어지는 코드이다. 너무 직접 떄려박아두잖아?
여기서 방법이 3가지가 있다고 한다...생성자 삽입
, 수정자 삽입
, 필드 주입
이 있는데 우선 생성자삽입부터 봐보도록하자
public class Car {
private Tire tire;
public Car(Tire tire) {
this.tire = tire;
}
생성자 삽입은 의존성 주입 패턴 중 하나로, 객체가 생성될 때 생성자를 통해 필요한 의존성을 주입하는 방식인데 위의 예제에서는 Car 객체가 생성될 때 Tire 객체를 생성자에 전달하고, 이를 통해 Car 객체는 Tire 객체에 대한 의존성을 얻는 방식이다!!!!
여기서 부터가 중요해 졸지마!!!
이 패턴의 주요 원리는 객체의 생성과 동시에 필요한 의존성을 제공함으로써, 객체가 자신의 책임을 수행하는 데 필요한 모든 종속성을 갖도록 보장하는 것이지! 이렇게 함으로써 객체의 불완전한 상태를 방지하고, 코드의 가독성과 유지 관리성을 높일 수 있게 되는것이다!!!이해했나? 안됬으면 한번더 봐봐...
public class Car {
private Tire tire;
public Car() {
// 기본 생성자
}
public void setTire(Tire tire) {
this.tire = tire;
}
수정자 삽입은 의존성 주입 패턴 중 하나로, 객체가 생성된 후 필요한 의존성을 수정자(setter) 메서드를 통해 주입하는 방식이다 위의 예제에서는 Car 객체가 생성된 후 setTire() 메서드를 통해 Tire 객체에 대한 의존성을 얻는것이지...
이 패턴의 주요 원리는 객체가 생성된 후에도 의존성을 변경하거나 추가할 수 있도록 함으로써, 객체의 유연성을 높이는 것!! 따라서 실행 시간에 객체의 의존성을 변경하거나, 선택적인 의존성을 다루는 데 적합하다고 할수있다!
public class Car {
@Autowired
private Tire tire;
필드 주입은 의존성 주입 패턴 중 하나로, 객체의 필드에서 직접적으로 의존성을 주입하는 방식. 위의 예제에서는 @Autowired 어노테이션이 붙은 tire 필드에 Tire 객체에 대한 의존성이 주입되게 된다.
이 패턴의 주요 원리는 의존성 주입 프레임워크(Spring 같은)가 클래스의 메타데이터를 읽고, 해당 필드에 적절한 객체를 주입해주는 것인데 문제는 코드가 간결해지는 장점이 있지만, 테스트하기 어렵고 클래스가 스프링과 같은 컨테이너에 너무 의존하게 되는 단점도 존재한다...
이로서 끝!!!! 모든것을 다 알아봤다...
원하던 목표 쉽지않구먼...하지만 기초부터 알아간다는 느낌 중요하지 중요하지!!!!!!
스프링을 하게 되고 어쨋든 프레임워크를 써야하니까 이 모든것들이 중요하다고 여겨진다....
이제부터는 나아가는 일만 남았다!!발목잡는 문제 하나씩 제끼면서 나가보자고!!!!!!