프로그램의 흐름을 직접 제어하는 것이 아니라 외부에 제어권을 넘겨 관리하게 하는 것을 제어의 역전이라고한다.
상세히 말하면 객체의 생성과 관리를 외부에서 한다면 제어권을 넘기게 되어 제어의 역전이 발생한 것이다.
프레임워크는 제어의 역전 개념이 적용된 대표적인 기술이다.
프레임워크와 라이브러리를 구분할 때 IOC 개념이 중요하다.
개발자는 필요한 Library 들을 선택하고, 연결하고, 설정하는 모든걸 다 직접 해야함
세부적으로 보면 라이브러리를 통해 객체를 생성하고
메소드를 호출하는 것을 개발자가 직접하기에 제어권이
코드 자체(개발자)에게 있는 것이다.
개발자가 직접 구현한것 혹은 Library 들을 연결하고, 설정하는 것들을 제공함
개발자가 기능 구현에 필요한 특정 코드를 프레임워크에 작성하면
프레임워크가 알아서 객체를 생성하고 메소드를 호출해준다.
즉 제어권이 프레임워크에 있는 것이다.
스프링에서는 사용할 객체를 직접 생성하지 않고 객체의 생성과 생명주기 관련해서는 Spring 컨테이너에 위임을 하여 제어권을 넘기게 된다. 이것이 Spring에서의 제어의 역전 IoC다.
IoC를 통해 ID(의존성 주입), 관점 지향 프로그래밍(AOP)등이 가능해지는 것이다. 이번 포스팅 글에서는 Spring에서의 DI를 집중적으로 다루어 보려고 한다.
스프링 빈 자동 등록 방법: @Repository, @Service, @Contorller, @Component
<-@ComponentScan
스프링 빈 수동 등록 방법: @Bean + Method
의존성 주입은 제어 역전의 방법 중 하나로, 사용할 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용하는 방식이다.
스프링 컨테이너에서 객체를 찾아 의존 객체 타입에 맞게 넣어준다.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicydiscountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
/*
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicydiscountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
*/
}
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;}
}
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
Test 코드를 짤 때 순수 자바로 단위 Test Code를 만든다고 한다.
스프링을 띄우고 하나 하나 테스트를 돌리면 굉장히 시간이 오래 걸리기 때문이다.
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
항상 생성자 주입을 선택하고 그리고 가끔 의존 객체를 변경할 상황이 생긴다면 수정자 주입을 선택하면 된다.
일반 메서드 주입, 필드 주입은 사용하지 않는게 좋다.