SoC: Seperation of Concern
관심사의 분리가 필요한 이유는 SRP와 DIP를 위해서이다.
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
@Autowired
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository);
}
}
AppConfig
는 구현 객체를 생성하고 연결하는 책임을 가지는 별도의 설정 클래스이다.구현 객체를 생성하고 연결하는 책임은
AppConfig
에 있다. ➡️ “SRP”
AppConfig
가 클라이언트 코드 대신 객체 인스턴스를 생성하고, 의존 관계를 주입한다. ➡️ “DIP”
AppConfig
가 의존 관계를 주입하므로 클라이언트 코드는 변경되지 않는다. ➡️ “OCP”
IoC: Inversion of Control
제어의 역전은 프로그램의 제어 흐름을 개발자가 아닌 외부에서 관리하는 것을 말한다.
AppConfig
등장 이후로 구현 객체는 자신의 로직을 실행하는 역할만 담당하게 되었다.AppConfig
에게 넘겨졌다.프레임워크와 라이브러리의 관계를 생각해보자.
프레임워크의 통제권은 개발자가 아닌 프레임워크 자체에 있다. 개발자는 프레임워크가 제공하는 틀 안에서 코드를 작성해야 한다. 반면 라이브러리의 통제권은 재발자에게 있다. 개발자는 기능 구현에 필요한 라이브러리를 불러서 코드를 작성할 수 있다.
DI: Dependency Injection
애플리케이션 실행 시점에 외부에서 실제 구현 객체를 생성하고, 클라이언트에 전달하여 클라이언트와 서버가 실제 의존 관계를 맺는 것을 의존 관계 주입이라고 한다.
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
}
AppConfig
처럼 객체를 생성하고 관리하면서 의존 관계를 연결해 준다.AppConfig
스프링 기반으로 변경
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(
memberRepository(), discountPolicy());
}
...
}
@Configuration
, @Bean
을 통해 스프링 컨테이너에 스프링 빈으로 등록한다.MemberApp
에 스프링 컨테이너 적용
public class MemberApp {
public static void main(String[] args) {
ApplicationContext applicationContext
= new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService
= applicationContext.getBean("memberService", MemberService.class);
...
}
}
ApplicationContext applicationContext
= new AnnotationConfigApplicationContext(AppConfig.class);
ApplicationContext
를 스프링 컨테이너라고 한다.@Configuration
이 붙은 AppConfig
를 설정 정보로 사용한다.@Bean
이 붙은 메서드를 모두 호출하여 반환된 객체를 스프링 컨테이너에 등록한다.@Bean
이 붙은 메서드의 이름을 스프링 빈의 이름으로 사용한다.