[Spring/SpringBoot] 의존 관계 주입 DI(Dependency Injection)
2024. 12. 15. 23:06ㆍCS/Spring

의존 관계 주입
- 애플리케이션 실행 시점(런타임)에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결되는 것을 의존관계 주입이라고 함
- 객체 인스턴스를 생성하고, 그 참조값을 전달해서 연결함
- 의존 관계 주입의 장점
- 클라이언트 코드를 변경하지 않고, 클라이언트가 호출하는 대상의 타입 인스턴스를 변경할 수 있음
- 정적인 클래스 의존관계를 변경하지 않고, 동적인 객체 인스턴스 의존관계를 쉽게 변경할 수 있음
- (ex) AppConfig의 의존관계 인스턴스 이름나 변경해주면됨 다른 코드/클래스 건드릴 필요 없음
의존 관계 주입 예시 코드
**import hello.core.discount.DiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;**
@Component
public class OrderServiceImpl implements OrderService{
//DIP 위반 -> 인터페이스 뿐만 아니라, 구현에도 의존하고 있다.
//private final MemberRepository memberRepository= new MemoryMemberRepository();
//private final DiscountPolicy discountPolicy= new FixDiscountPolicy();
//private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
//해결책 -> 인터페이스에만 의존하도록 의존관계 변경
private final MemberRepository memberRepository;
**private final DiscountPolicy discountPolicy;**
@Autowired
//생성자를 통해서 의존관계 주입
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy){
this.memberRepository = memberRepository;
this.discountPolicy = rateDiscountPolicy;
}
public class AppConfig{
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
}
- public interface DiscountPolicy { int discount(Member member, int price); }
- OrderServiceImpl은 DiscountPolicy인터페이스에 의존함 → 실제 어떤 구현 객체가 사용될지는 모름
- 의존 관계는 정적인 클래스 의존 관계와, 실행 시점에 결정되는 동적인 객체(인스턴스) 의존 관계 둘을 분리해서 생각해야함
정적인 클래스 의존관계
- 클래스가 사용하는 import 코드만 보고 쉽게 의존관계 판단 가능 → 애플리케이션을 실행하지 않아도 분석 가능
- but, 이러한 클래스 의존관계 만으로는 실제 어떤 객체가 OrderServiceImpl에 주입될지 알 수 없음
//OrderServiceImpl의 import문 일부
import hello.core.discount.DiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
동적인 객체 인스턴스 의존 관계
//AppConfig의 코드 일부
public DiscountPolicy discountPolicy(){
return new RateDiscountPolicy();
}
@Component
public class RateDiscountPolicy implements DiscountPolicy{
private int discountPercent = 10;
@Override
public int discount(Member member, int price) {
if(member.getGrade()== Grade.VIP){
return price * discountPercent/100;
}else{
return 0;
}
}
}
- 애플리케이션 실행 시점에 실제 생성된 객체 인스턴스의 참조가 연결된 의존관계
- OrderServiceImpl에 주입될 구현 객체는 DiscountPolicy 인터페이스를 구현한 RateDiscountPolicy가 될 것
'CS > Spring' 카테고리의 다른 글
[Spring/Springboot] AOP 관점 지향 프로그래밍 (0) | 2024.12.15 |
---|---|
[Spring/Springboot] API, 프레임워크, 라이브러리의 차이 (0) | 2024.12.15 |
[Spring/Springboot] Bean/싱글톤 패턴/컴포넌트 스캔 (0) | 2024.12.15 |
[Spring/Springboot] 제어의 역전 IoC(Inversion of Control) (0) | 2024.12.15 |
[Spring/MVC] Controller, Repository, DTO, Domain, Config의 역할 (0) | 2024.08.26 |