DI 용기를 작성해서 의존 주입을 이해합니다. 처음부터!(첫 부분)
이 강좌에서, 우리는 자바로 아주 간단하지만 기능이 완비된 의존항 주입 용기를 처음부터 구축할 것이다.다음은 업무를 쉽게 관리할 수 있는 몇 가지 규칙이다.
main()
방법.DI 단계 0: 기본 예
Find the source code of this section on github
우리는 매우 기본적인 예로부터 시작한다.우리는 두 종류를 원한다. 우리는 그것들
ServiceA
과 ServiceB
이라고 부르고, ServiceA
는 그것의 일을 완성하기 위해 ServiceB
가 필요하다.좋아, 너는 static
방법으로 그것을 실현하고 그것을 완성할 수 있어!다음은 다음과 같습니다.public class ServiceA {
public static String jobA(){
return "jobA(" + ServiceB.jobB() + ")";
}
}
public class ServiceB {
public static String jobB(){
return "jobB()";
}
}
public class Main {
public static void main(String[] args) {
System.out.println(ServiceA.jobA());
}
}
이 코드를 실행하면 다음과 같이 인쇄됩니다.jobA(jobB())
쿨!그럼, 왜 더 많은 일을 해야 합니까?좋아요.DI 단계 1: 정적 참조에서 벗어나기
Find the source code of this section on github
우리가 단계 0에서 발견한 주요 문제는 정적 방법만 있어 매우 긴밀한 결합을 초래한다는 것이다.우리는 우리의 서비스가 서로 이야기하는 대상이 되기를 바란다. 그러면 우리는 필요에 따라 그것들을 교체할 수 있기를 바란다.이제 질문이 왔습니다. ServiceA에서 어떤 ServiceB와 대화하는지 어떻게 알 수 있습니까?가장 기본적인 생각은 ServiceB 인스턴스를 ServiceA의 구조 함수에 간단하게 전달하는 것입니다.
public class ServiceA {
private ServiceB serviceB;
public ServiceA(ServiceB serviceB){
this.serviceB = serviceB;
}
public String jobA(){
return "jobA(" + this.serviceB.jobB() + ")";
}
}
서비스 B 는 크게 달라지지 않았습니다.public class ServiceB {
public String jobB() {
return "jobB()";
}
}
... Main
현재 대상을 조립한 다음에 jobA
방법을 호출할 수 있습니다. public static void main(String[] args) {
ServiceB serviceB = new ServiceB();
ServiceA serviceA = new ServiceA(serviceB);
System.out.println(serviceA.jobA());
}
별거 아니야, 그렇지?우리는 확실히 몇 가지를 개선했다.ServiceB
에서 사용한 ServiceA
의 실현을 대체할 수 있으며, 심지어는 다른 하위 클래스의 실현일 수도 있다.DI단계 2: 인터페이스 사용
Find the source code of this section on github
따라서 모든 서비스에 인터페이스를 사용하자.그것들은 매우 간단하다. (나는 실제 클래스를 각각
ServiceAImpl
과 ServiceBImpl
로 이름을 바꾸었다.public interface ServiceA {
public String jobA();
}
public interface ServiceB {
public String jobB();
}
현재 ServiceAImpl
에서 우리는 실제 인터페이스를 사용할 수 있다.public class ServiceAImpl implements ServiceA {
private final ServiceB serviceB;
public ServiceAImpl(ServiceB serviceB){
this.serviceB = serviceB;
}
// jobA() is the same as before
}
또한 Dell의 main()
접근 방식도 향상되었습니다. public static void main(String[] args) {
ServiceB serviceB = new ServiceBImpl();
ServiceA serviceA = new ServiceAImpl(serviceB);
System.out.println(serviceA.jobA());
}
대상을 향한 측면에서 볼 때 이것은 간단한 용례로 볼 때 충분히 받아들일 수 있다.만약 네가 벌을 면할 수 있다면, 그것은 여기까지다.하지만, 당신의 프로젝트가 점점 커지면서...main()
방법에서 서비스 네트워크를 만드는 것은 갈수록 복잡해질 것이다.DI단계 3: 세터 사이클 깨기
Find the source code of this section on github
ServiceA
가 필요할 뿐만 아니라 반대로 우리는 순환이 있다고 가정합시다.물론 우리는 ServiceB
류의 구조 함수에서 다음과 같은 매개 변수를 설명할 수 있다.
// constructor examples
public ServiceAImpl(ServiceB serviceB) { ... }
public ServiceBImpl(ServiceA serviceA) { ... }
... 그러나 이것은 우리에게 이롭지 않다. 우리는 이 두 종류 중 어떤 실제 실례도 만들 수 없다.*Impl
의 실례를 만들려면 ServiceAImpl
의 실례를 먼저 필요로 하고 ServiceB
의 실례를 만들려면 ServiceBImpl
의 실례를 먼저 필요로 한다.우리는 교착 상태에 빠졌다.Side note: there is actually a way out of this by using proxies. However, we're not going to take that route here.
그럼 우리 어떻게 해야 되지?순환 의존 관계를 처리해야 하기 때문에, 우리는 먼저 서비스를 만들고 그것을 연결해야 한다.우리는 세터로 이 점을 해냈다.
public class ServiceAImpl implements ServiceA {
private ServiceB serviceB;
// no constructor anymore here!
@Override // <- added getter to ServiceA interface
public ServiceB getServiceB() { return serviceB; }
@Override // <- added setter to ServiceA interface
public void setServiceB(final ServiceB serviceB) { this.serviceB = serviceB; }
// jobA() same as before
}
DellServiceA
접근 방식은 다음과 같습니다. public static void main(String[] args) {
// create instances
ServiceB serviceB = new ServiceBImpl();
ServiceA serviceA = new ServiceAImpl();
// wire them together
serviceA.setServiceB(serviceB);
serviceB.setServiceA(serviceA);
// call business logic
System.out.println(serviceA.jobA());
}
너는 도안을 볼 수 있니?먼저 대상을 만들고 그것들을 연결해서 서비스 맵(즉 서비스 네트워크)을 형성한다.근데 왜 여기 안 멈춰요?
main()
아주 많아졌다.다음
다음 블로그에서 우리는 현재 수동으로 진행되고 있는 배선을 어떻게 자동화하는지 토론할 것이다.
Reference
이 문제에 관하여(DI 용기를 작성해서 의존 주입을 이해합니다. 처음부터!(첫 부분)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/martinhaeusler/understanding-dependency-injection-by-writing-a-di-container-from-scratch-part-1-1hdf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)