DI(Dependency Injection) 은 기본적으로 Bean 끼리만 가능하다.
Spring 의존성 주입 DI(Dependency Injection) 와 순환 참조
Spring 4.3 이상 부터는, 어떠한 Class에 생성자가 1개 뿐이고 해당 생성자로 주입받는 Reference 변수들이 Bean으로 등록되어 있다면 그 Bean을 자동으로 주입한다. (
@Autowried
생략 가능)
No qualifying bean Error : Bean 주입에 실패했다는 에러
🤔 DI (Dependency Injection) 이란?
의존성 주입. 생성된 Bean을 객체에 넣어주는걸 의미한다. 보통 @Autowired
를 통해 주입하지만 위에서 말한 특성을 이용해 생성자를 통해서도 주입이 가능하다. 만약 사용해야 하는 객체에 Bean
이 제대로 주입되지 않았다면 Application은 정상적으로 실행조차 되지 않을것이다.
public class TestController{
private TestRepository testRepository;
//@Autowired
public TestController(TestRepository testRepository){
this.testRepository = testRepository;
}
}
@Autowired
를 주석처리해도, 클래스의 생성자가 1개 이고 TestRepository
가 Bean
에 등록이 되어 있기 때문에 TestController
는 정상적으로 동작한다.
🤔 순환참조(Circular Dependency)? A가 B를 참조하고, B가 A를 참조하는것.
하지만 위의 방법처럼 생성자로 Bean
을 주입받을때 주의해야 할 부분이 있다. 바로 순환참조 라는 부분인데, 만약 TestRepository
와 SampleRepository
가 서로 필요해 각각의 클래스에서 사용해야 한다고 가정해보자. 생성자를 통해 Bean
을 주입 받는다고 한다면 아래와 같은 코드가 될 것이다.
@Component
public class TestRepository{
private SampleRepository sampleRepository;
//@Autowired
public TestRepository(SampleRepository sampleRepository){
this.sampleRepository = SampleRepository
}
}
@Component
public class ampleRepository{
private TestRepository testRepository;
//@Autowired
public SampleRepository(TestRepository testRepository){
this.testRepository = testRepository
}
}
두 클래스 모두 다
- 생성자가 1개 뿐
- 주입받는 Reference 변수들이 Bean으로 등록
따라서 @Autowired
는 생략이 가능하다.
Bean을 주입하는 과정에서 A ➡ B ➡ C 순으로 DI를 하면 상관없지만, 여기서는 A와 B가 서로 참조하는 형태로 구성되어 있으므로 어떤 객체를 먼저 Bean으로 만들어야 하는지 알 수 없게 된다.
따라서 의존성을 주입할때는 순서를 맞춰서 잘 주입해야한다.
🤫 순환 참조 해결방법
DI를 순서에 맞게 잘 하는게 좋지만, 그렇지 않을 경우에는
Field Injection, Setter Injection 을 사용해 주입하는 방법이 있다.
먼저 Filed Injection 이다.
주의사항 : final을 붙이면 안된다.
@Component
public class TestRepository{
@Autowired private SampleRepository sampleRepository;
}
@Component
public class SampleRepository{
@Autowired private TestRepository testRepository;
}
필드 자체에서 @Autowired
를 사용해 주입하는 방법이다.
다음은 Setter Injection 이다. 특정 클래스 하나를 만들어서 하나의 클래스CircularDependencyTest
에서 TestRepository
와 SampleRepository
의 Bean
을 주입하는 방법이다.
@Component
public class TestRepository{
public void doSomethingTest(){
...
}
}
@Component
public class SampleRepository{
public void doSomethingSample(){
...
}
}
public class CircularDpendencyTest{
private SampleRepository sampleRepository;
private TestRepository testRepository;
public CircularDpendencyTest(SampleRepository sampleRepository, TestRepository testRepository){
this.sampleRepository = sampleRepository;
this.testRepository = testRepository;
}
}
'개발공부 > Spring' 카테고리의 다른 글
[SpringBoot] Spring 에서 자동설정의 이해와 구현 (AutoConfiguration) (0) | 2020.05.03 |
---|---|
[SpringBoot]Spring AOP와 프록시 패턴 (0) | 2020.05.01 |
[SpringBoot] IoC 컨테이너와 Bean (0) | 2020.05.01 |
[SpringBoot]Spring IoC(Inversion of Control) (0) | 2020.05.01 |
Spring - JPA에서 Like 기능 수행하기. (0) | 2020.05.01 |