주녁, DevNote
article thumbnail

지적과 댓글은 언제나 환영합니다!



1. 의존성 주입이란?

 

스프링에서 지원하는 핵심 프로그래밍 모델 중 하나로

말 그대로 의존관계를 외부에서 결정해주는 디자인 패턴이다.



1.1. 의존관계?

 

의존관계는 쉽게 이야기하자면

한 쪽이 변경되면 다른 한쪽도 변경되는 관계로 말할 수 있다.

<code />
public class Customer{ // 초기모델 private final int id; // 고유 ID private final String grade; // 회원 등급 private final DiscountPolicy discountPolicy; // 할인정책 } public class Customer{ // 변경 후 모델 private final int id; private final String grade; private final VipDiscountPolicy vipPolicy; // VIP 할인정책으로 변경 }

고객마다 할인정책을 정의해준 초기 모델에서

VIP 고객전용으로 할인정책을 변경하고 싶다면

생성자, Getter, Setter 등을 모두 수정해야 한다.

(이미 다른 서비스에서도 할인율을 사용하고 있다면 더 많은 수정이 필요하다)

 

이러한 관계를 Customer와 DiscountPolicy는 의존관계에 있다고 할 수 있다.

 

하지만, 회원 등급은 처음부터 VIP가 아닐텐데, 나중에 결정할 수는 없는걸까?

= 의존성을 최대한 나중에 결정할 순 없을까?



1.2. 외부에서 결정하는 의존성

 

할인 정책의 행동은 이미 알고있다. 할인해주는 행동이다.

VIP 할인 정책의 행동은 무엇일까? 역시 할인이다.

<code />
discountPolicy.discount(); vipPolicy.discount();



각 할인 정책은 같은 행동을 하기 때문에 interface로 묶을 수 있다.

<code />
public interface discountPolicy{ // 할인 정책 인터페이스는 public double discount(); // 할인을 한다. } public class normalPolicy implementation discountPolicy{ public double discount(){ return 0.15; } // 할인율 15 } public class vipPolicy implementation discountPolicy{ public double discount(){ return 0.30; } // 할인율 30 }



이런 식으로 interface를 통해 정의하게 되면

아래와 같이 의존관계를 설정할 수 있다.

이를 생성자 주입 방식이라고 하며, Spring에서 권장하는 방법이다.

다른 방법들도 있지만 공식적으로 권장하지 않는다.

<code />
public class Customer{ ... private final discountPolicy discountPolicy; Customer(discountPolicy policy){ this.discountPolicy = policy; } } public static void main(){ ... Customer normal = new Customer(normalDiscountPolicy); Customer vip = new Customer(VipDiscountPolicy); }



생성자를 호출할 때 할인 정책을 설정할 수 있게 되므로

Customer가 생성될 때(로그인 시, 비로그인 주문 시 등등)

할인 정책을 결정할 수 있게 된다.

이게 바로 의존성을 외부에서 주입한다는 의미이다.

 

1.3. 스프링과 DI

실제로 스프링에서는 아래와 같이

@Autowired 태그를 통해서

DB 작업을 위한 repository 설정이나, Service 설정 등

Bean 객체들을 의존성을 주입으로 사용하도록 권장하고 있다.

<code />
@Service public class UserService { private UserRepository userRepository; private MemberService memberService; @Autowired public UserService(UserRepository userRepository, MemberService memberService) { this.userRepository = userRepository; this.memberService = memberService; } }

 

때문에 변경이 필요한 부분은 적절하게 의존성 주입이 가능하도록

interface를 활용하여 설계하여야 한다.

 

출처

mangkyu님 블로그

인프런 스프링 MVC 강의 1편

인프런 스프링 핵심 원리 기본편

 

profile

주녁, DevNote

@junwork

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!