김영한 이사 스프링 핵심 원리 - 기본편 강의와 따로 찾아본 내용을 정리한 글 입니다.
스프링 컨테이너
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
public OrderService orderService() {
return new OrderServiceImpl(
memberRepository(),
discountPolicy());
}
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
public DiscountPolicy discountPolicy() {
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
}
스프링의 핵심은 추상화 (interface) 와 구현 (implementation) 이다. 이전의 강의에서 비즈니스 로직은 추상화 인터페이스에 의존하도록 설계하였고 그것에 대한 구현은 AppConfig 에서 따로 설정해주도록 분리하였다. 이를 Inversion Of Control 이라고도 한다. 위의 코드는 스프링을 이용하지 않고 순수 자바코드로 구현한 의존관계 설정 코드이다.
순수 자바 대신 스프링을 사용하는 이유
자바 코드로도 구현이 가능하지만 스프링을 사용하는 이유는 편의성이 때문이다. 서로가 얽히는 의존 관계 속에서 return new MemberService() 를 여러번 하면 여러 객체가 생겨나서 나중에 서버가 복잡해지는 문제가 생긴다. 그래서 하나의 객체를 Bean 으로서 싱글톤으로 관리하기 위해 스프링을 사용한다.
위의 코드에서 스프링을 사용해서 코드 리팩토링을 하게 되면 @Configuration 과 @Bean 어노테이션을 사용하게 되는데 각각의 의미를 살펴보도록 하자.
@Configuration : 의존 관계 주입 설정
@Bean : 객체를 스프링 컨테이너에 빈으로서 등록
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new FixDiscountPolicy();
}
}
Bean Factory 와 Application Context
흔히 말하는 스프링 컨테이너가 바로 Application Context 또는 Bean Factory 이다. Application Context 가 Bean Factory 의 기능을 상속 받는다. `getBean()` 메소드의 경우에도 Bean Factory 에서 제공해주는 메소드이다.
스프링 설정 형식은 이전에 사용한 애노테이션 기반 자바 코드가 제일 많이 사용되지만 xml 파일로도 가능하다. 이렇게 다양한 설정 형식이 가능한 이유는 빈 설정 메타 정보 Bean Definition 으로 추상화 되어있기 때문이다. 결론적으로는 어떠한 설정 파일이라도 Bean Definition 으로 추상화되어 있어 이것만 파악하면 된다.
BeanDefinition 정보
- BeanClassName: 생성할 빈의 클래스 명(자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
- factoryBeanName: 팩토리 역할의 빈을 사용할 경우 이름, 예) appConfig
- factoryMethodName: 빈을 생성할 팩토리 메서드 지정, 예) memberService
- Scope: 싱글톤(기본값)
- lazyInit: 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때 까지 최대한 생
성을 지연처리 하는지 여부 - InitMethodName: 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명
- DestroyMethodName: 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
- Constructor arguments, Properties: 의존관계 주입에서 사용한다. (자바 설정 처럼 팩토리 역할의
빈을 사용하면 없음)
'☘️Spring' 카테고리의 다른 글
[Spring] JPA N+1 문제 해결 (35) | 2023.10.30 |
---|---|
[Spring] MockMvcTest vs End-to-End Tests (1) | 2023.10.26 |
[Spring] web mvc 코드로 이해하기 (0) | 2023.09.02 |
[Spring] 의존관계 자동/수동 주입 (0) | 2023.07.09 |
[Spring] 싱글톤 컨테이너 (2) | 2023.07.06 |