Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other objects with which they work) only through constructor arguments, arguments to a factory method(팩터리 메서드 패턴 이용한 생성자 주입), or properties that are set on the object instance after it is constructed or returned from a factory method(생성 된 이후, 세터 이용한 초기화 방식, 이는 생성과 초기화를 분리한다.) The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies on its own by using direct construction of classes or the Service Locator pattern.
어떤 클래스의 스스로에 대한 실행(생성, 초기화)의 흐름(Controlling)을 외부의 컨테이너가 갖고 있다. 그래서 IoC임.
Code is cleaner with the DI principle, and decoupling is more effective when objects are provided with their dependencies. The object does not look up its dependencies and does not know the location or class of the dependencies. As a result, your classes become easier to test, particularly when the dependencies are on interfaces or abstract base classes(DIP), which allow for stub or mock implementations to be used in unit tests.
DI exists in two major variants:
필드는 소개도 안해준다.
Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency. Calling a static
factory method with specific arguments to construct the bean is nearly equivalent, and this discussion treats arguments to a constructor and to a static
factory method similarly.
The following example shows a class that can only be dependency-injected with constructor injection:
public class SimpleMovieLister {
// the SimpleMovieLister has a dependency on a MovieFinder
private final MovieFinder movieFinder;
// a constructor so that the Spring container can inject a MovieFinder
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// business logic that actually uses the injected MovieFinder is omitted...
}
위는 생성자 기반으로 의존관계 주입을 받는 클래스이다.
하지만 위 코드만 봐서는 그 어떤 외부 컨테이너에 대한 의존성은 없다 POJO임.
Notice that there is nothing special about this class. It is a POJO that has no dependencies on container specific interfaces, base classes, or annotations.
Constructor argument resolution matching occurs by using the argument’s type. If no potential ambiguity exists in the constructor arguments of a bean definition, the order in which the constructor arguments are defined in a bean definition is the order in which those arguments are supplied to the appropriate constructor when the bean is being instantiated. Consider the following class:
💡 resolve는 … 주소를 참조하다라는 의미라고 한다. 예전부터 의미를 확실히 하지 못해서 의문이었다. 나아가서는 외부 커넥션과의 연결을 의미하기도 한다.
참고 : https://www.pcmag.com/encyclopedia/term/resolve
https://softwareengineering.stackexchange.com/questions/302404/what-does-resolving-mean-in-programing
더 엄밀하게는, DNS와 IP의 관계처럼 DNS를 통해 IP를 찾는 과정을 resolve라고 한다. IP는 변할 수 있지만 DNS는 변하지 않는다. 다만 도메인은 그때그때 변하는 IP에 매칭된다. 우리가 변수로 메모리의 주소를 참조할때, 메모리 주소는 몰라도 된다. IP주소를 몰라도 되는 것 처럼, 다만 도메인은 알아야 하는 것 처럼 변수명은 알아야 한다. 이때 변수명으로 메모리 주소를 찾아가는걸 resolving이라고 함.