[Spring 다시보기] Spring DI

DI 란?

  • Dependency Injection
  • 의존성 주입
  • 객체를 직접 생성하는 것이 아닌 외부에서 생성한 후 주입하는 것

DI를 사용하는 이유

  • 재사용성을 높여줌
  • 테스트에 용이함
  • 코드를 단순하게하고 읽기 쉽게 만들어 준다.
  • 종속성이 감소하여 변경에 민감하지 않음
  • 결합도를 낮추면서 유연성과 확장성을 향상 시킬 수 있다.
  • 객체 간의 의존관계를 설정할 수 있다.

의존성 주입 방법

  • Construct Injection
@Service
public class TestA {

    private final TestB testB;

    public TestA(TestB testB) {
        this.testB = testB;
    }
}
  • Field Injection
@Service
public class TestB {

    @Autowired
    private TestC testC;

}
  • Setter Injection
@Service
public class TestC {

    private TestB testB;

    public void setTestB(TestB testB) {
        this.testB = testB;
    }
}

권장하는 방법

  • Construct injection 방식을 권장한다.
순환참조…
  • field injection 이나 setter injection 의 경우, 객체를 생성하는 시점에 순환참조가 일어나는지 알 수가 없다.
  • TestB, TestC 두개를 Construct injection 으로 변경하여 테스트 하였다.
@Service
public class TestB {

    private TestC testC;

    public TestB(TestC testC) {
        this.testC = testC;
    }
}

@Service
public class TestC {

    private final TestB testB;

    public TestC(TestB testB) {
        this.testB = testB;
    }
}
***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   testA defined in file [~/test/target/classes/com/example/test/TestA.class]
┌─────┐
|  testB defined in file [~/test/target/classes/com/example/test/TestB.class]
↑     ↓
|  testC defined in file [~/test/target/classes/com/example/test/TestC.class]
└─────┘
  • 이렇게 사용하게되면 객체를 생성할때 확인할 수 있으므로, runtime 이 아닌 build 타임에 순환참조를 잡을 수 있다.
    • @Lazy 와 같은 방식으로 대응은 할 수 있겠지만… 추천하는 방법은 아니므로 순환참조를 끊는게 중요한 포인트 같다.

Related Posts