spring
DI (Dependency Injection) 및 IoC (Inversion of Control)
수색…
비고
대형 소프트웨어 응용 프로그램의 소스 코드는 대개 여러 개의 장치로 구성됩니다. 유닛의 정의는 일반적으로 사용되는 프로그래밍 언어에 따라 다릅니다. 예를 들어, 절차 적 프로그래밍 언어 (C와 같이)로 작성된 코드는 functions
또는 procedures
로 구성됩니다. 마찬가지로 객체 지향 프로그래밍 언어 (Java, Scala, C # 등)의 코드는 classes
, interfaces
등으로 구성됩니다. 이러한 코드 조직 단위는 전체 소프트웨어 응용 프로그램을 구성하는 개별 단위로 생각할 수 있습니다.
응용 프로그램에 여러 개의 유닛이있는 경우 한 유닛이 다른 유닛을 사용하여 기능을 완료해야 할 때 해당 유닛 간의 상호 의존성이 커집니다. 종속 단위는 consumers
및 특정 기능의 providers
로 의존하는 단위로 생각할 수 있습니다.
가장 쉬운 프로그래밍 방식은 소비자가 응용 프로그램의 전체 실행 중 어떤 시점에서 어떤 제공자를 인스턴스화하고, 사용하고, 파괴해야하는지 결정함으로써 소프트웨어 응용 프로그램의 흐름을 완전히 제어하는 것입니다. 소비자는 실행 흐름 중에 공급자에 대한 완전한 제어권을 가지며 이는 소비자를위한 dependencies
합니다. 공급자가 자체 종속성이있는 경우 소비자는 공급자의 초기화 (및 해제) 방법에 대해 걱정해야 할 수 있으므로 소프트웨어의 단위 수가 늘어남에 따라 제어 흐름이 점점 더 복잡해집니다. 이 방법은 또한 단위 간의 결합을 증가시켜 소프트웨어의 다른 부분을 손상시키지 않고 단위를 개별적으로 변경하는 것을 점점 더 어렵게 만듭니다.
Inversion of Control (IoC)은 단위 발견, 인스턴스화 및 파괴와 같은 제어 흐름 활동을 소비자 및 공급자와 독립적 인 프레임 워크로 아웃소싱하는 것을 옹호하는 설계 원칙입니다. IoC의 기본 원칙은 소비자와 공급자를 분리하여 소프트웨어 단위가 종속성을 발견, 인스턴스화 및 정리하고 장치가 자신의 기능에 집중할 수 있도록 해줄 필요가 없도록 해방시키는 것입니다. 이 디커플링은 소프트웨어를 확장 가능하고 유지 보수 가능하게 유지하는 데 도움이됩니다.
의존성 주입 은 종속성 (제공자)의 인스턴스를 찾아서 인스턴스화해야하는 대신 소프트웨어 단위 (소비자)에 주입하는 제어 원리의 반전을 구현하는 기술 중 하나입니다.
Spring 프레임 워크는 코어에 의존성 주입 모듈을 포함하고있어 Spring 관리 빈이 다른 Spring 관리 빈에 의존성으로 주입되도록한다.
XML 구성을 통해 수동으로 종속성 삽입
다음 Java 클래스를 고려하십시오.
class Foo {
private Bar bar;
public void foo() {
bar.baz();
}
}
보시다시피, Foo
클래스는 foo
메소드가 성공적으로 작동하도록 다른 클래스 Bar
의 인스턴스에서 baz
메소드를 호출해야합니다. Bar
는 Foo
가 Bar
인스턴스없이 올바르게 작동하지 않기 때문에 Foo
대한 종속성이라고합니다.
생성자 주입
스프링 프레임 워크에 XML 설정을 사용하여 스프링 관리 빈을 정의 할 때, Foo
타입의 빈은 다음과 같이 설정 될 수있다 :
<bean class="Foo">
<constructor-arg>
<bean class="Bar" />
</constructor-arg>
</bean>
또는 (좀 더 자세한) :
<bean id="bar" class="bar" />
<bean class="Foo">
<constructor-arg ref="bar" />
</bean>
두 경우 모두, Spring 프레임 워크는 먼저 Bar
의 인스턴스를 생성하고이를 Foo
의 인스턴스에 injects
합니다. 이 예제에서는 클래스 Foo
에 Bar
인스턴스를 매개 변수로 사용할 수있는 생성자가 있다고 가정합니다.
class Foo {
private Bar bar;
public Foo(Bar bar) { this.bar = bar; }
}
이 스타일은 의존성 ( Bar
인스턴스)이 클래스 생성자를 통해 주입 되기 때문에 생성자 삽입 으로 알려져 있습니다.
특성 주입
Bar
종속성을 Foo
에 주입하는 또 다른 옵션은 다음과 같습니다.
<bean class="Foo">
<property name="bar">
<bean class="Bar" />
</property>
</bean>
또는 (좀 더 자세한) :
<bean id="bar" class="bar" />
<bean class="Foo">
<property name="bar" ref="bar" />
</bean>
이를 위해서는 Foo
클래스가 다음과 같이 Bar
인스턴스를 받아들이는 setter 메서드를 필요로합니다.
class Foo {
private Bar bar;
public void setBar(Bar bar) { this.bar = bar; }
}
Java 구성을 통해 수동으로 종속성 삽입
XML 구성을 사용하여 위에 표시된 것과 같은 예제를 다음과 같이 Java 구성으로 다시 작성할 수 있습니다.
생성자 주입
@Configuration
class AppConfig {
@Bean
public Bar bar() { return new Bar(); }
@Bean
public Foo foo() { return new Foo(bar()); }
}
특성 주입
@Configuration
class AppConfig {
@Bean
public Bar bar() { return new Bar(); }
@Bean
public Foo foo() {
Foo foo = new Foo();
foo.setBar(bar());
return foo;
}
}
XML 설정을 통한 의존성 자동 종료
스프링 프레임 워크의 컴포넌트 스캔 기능을 사용할 때 종속성을 자동으로 적용 할 수 있습니다. autowiring이 작동하려면 다음 XML 구성을 작성해야합니다.
<context:annotation-config/>
<context:component-scan base-package="[base package]"/>
여기서 base-package
는 Spring이 구성 요소 검사를 수행해야하는 완전한 Java 패키지입니다.
생성자 주입
종속성은 다음과 같이 클래스 생성자를 통해 주입 될 수 있습니다.
@Component
class Bar { ... }
@Component
class Foo {
private Bar bar;
@Autowired
public Foo(Bar bar) { this.bar = bar; }
}
여기에서 @Autowired
는 Spring에 특정한 주석이다. Spring은 JSR-299 를 지원하여 다른 Java 기반 종속성 삽입 프레임 워크에 대한 애플리케이션 이식성을 지원합니다. 이렇게하면 @Autowired
를 @Inject
로 대체 할 수 있습니다.
@Component
class Foo {
private Bar bar;
@Inject
public Foo(Bar bar) { this.bar = bar; }
}
특성 주입
다음과 같이 setter 메소드를 사용하여 종속성을 주입 할 수도 있습니다.
@Component
class Foo {
private Bar bar;
@Autowired
public void setBar(Bar bar) { this.bar = bar; }
}
필드 주입
자동 와이어 링을 사용하면 다음과 같이 클래스 인스턴스 내의 필드를 직접 초기화 할 수도 있습니다.
@Component
class Foo {
@Autowired
private Bar bar;
}
Spring 버전 4.1+에서는 선택 적인 의존성을 위해 Optional 을 사용할 수 있습니다.
@Component
class Foo {
@Autowired
private Optional<Bar> bar;
}
동일한 접근법이 생성자 DI에도 사용될 수 있습니다.
@Component
class Foo {
private Optional<Bar> bar;
@Autowired
Foo(Optional<Bar> bar) {
this.bar = bar;
}
}
Java 구성을 통한 종속성 자동 실행
Java 구성을 통한 생성자 삽입은 다음과 같은 자동 와이어 링을 사용할 수도 있습니다.
@Configuration
class AppConfig {
@Bean
public Bar bar() { return new Bar(); }
@Bean
public Foo foo(Bar bar) { return new Foo(bar); }
}