기존에 순수 Java 코드를 사용하여 DIP와 OCP를 준수하여 의존성을 주입하는 코드를 알아보았다.
스프링 컨테이너를 사용하면 이러한 부분들을 훨씬 간편하게 사용할 수 있다.
( 2022.03.06 - [개발/Java] - [Java]순수 자바 코드로 DIP와 OCP를 준수하는 방법 )
먼저 간단한 설정 사례를 보자
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
객체의 생성을 담당하는 AppConfig 클래스에 @Configuration 어노테이션을 통해 설정 클래스로 등록한다.
이후 생성이 필요한 클래스를 생성하는 메서드에 @Bean 어노테이션을 통해
객체 생성과 동시에 스프링 컨테이너에 등록해준다.
등록된 빈은 아래와 같이 클래스명을 활용하여 camel case로 지정된다.
물론 @Bean(name="myBeanName") 으로 직접 부여할 수도 있다.
Bean Name | Bean Object |
memberService | MemberService@x01 |
memberRepository | MemberRepository@x02 |
discountPolicy | RateDiscountPolicy@x03 |
해당 빈들이 정상적으로 등록되었는지 테스트코드를 통해 살펴보자
public class ApplicationContextInfoTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
void findAllBean() {
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name=" + beanDefinitionName + " object=" + bean);
}
}
}
결과
문제는 코드상으로만 보면 딱히 깔끔해진것처럼 보이지 않는다는 점이다.
스프링을 통해 설정을 할 때 어떤 이점이 있을까?
- @Configuration 으로 생성한 객체는 싱글톤을 보장한다.
- AppConfig 클래스의 경우 실제 웹에서 많은 요청이 들어온다면, 매 요청마다 새롭게 클래스를 생성하게 될 것이다.
- 스프링 컨테이너에 등록된 Bean은 무상태(stateless) 하기 때문에, 요청시에 같은 인스턴스를 공유한다. - Bean으로 등록된 객체는 스프링이 제공하는 다양한 기능을 활용할 수 있다.
스프링 컨테이너의 최상위 인터페이스인 BeanFactory는 getBean() 메서드를 제공하고, BeanFactory를 상속한 ApplicatonContext 인터페이스는 다음과 같은 기능들을 제공한다. (위 두 인터페이스를 스프링 컨테이너라 한다)
- 메시지소스를 활용한 국제화 기능(지역에 따른 언어 분리)
- 환경변수를 통한 로컬, 개발, 운영 환경의 분리
- 이벤트 지원
- 파일, 클래스패스 및 외부 리소스의 편리한 조회 - Java 코드로 구현한 AppConfig 파일을 XML, Groovy 등으로도 설정할 수 있게 지원한다.
위에 설정한 장점들에 대한 조금 더 자세한 내용은 추후에 다루고자 한다.
해당 내용은 모두 인프런 김영한 팀장님의
"스프링 핵심원리 - 기본편" (https://inf.run/ccuv)을 바탕으로 작성되었다.
'개발 > Spring' 카테고리의 다른 글
[Spring] Kotlin + Spring 프로젝트 만들고 테스트 해보기 (0) | 2023.08.05 |
---|---|
[Spring] @RequestParam / @ModelAttribute / @RequestBody / @Requestpart (0) | 2023.07.22 |
[Spring] Security의 인가(Authorization) 실패 시 처리 (0) | 2023.07.02 |
[Spring] Security와 Jwt 사용을 통한 인증, 인가 도입기 (0) | 2023.06.25 |
[Spring] Bean을 Collection으로 호출하기 (0) | 2023.05.21 |