김영한님의 스프링 핵심 원리 - 기본편 강의 내용 중 '4강. 스프링 컨테이너와 스프링 빈'에 대한 내용을 정리해봤다.
직전 강의 '3강. 스프링 핵심원리 이해2 - 객체 지향 원리 적용'에서는 다형성만으로는 해결이 안되는 OCP, DIP에 대한 문제를 DI(의존관계 주입)를 통해 어떻게 해결했는지 다뤘다.
(*관련 글: https://yunb2.tistory.com/33)
그리고 'DI(의존관계 주입)를 할 때 필요한 곳에 직접 자바 객체를 생성하는 것이 아닌, 스프링 컨테이너에서 객체를 빈으로 등록하고 필요할 때마다 찾아서 쓸 때 장점은 어떤게 있을까?' 라는 질문으로 강의가 마무리가 됐다. 이번 강의부터는 스프링 컨테이너의 핵심 기능을 배우면서 이에 대한 답을 조금씩 찾아갈 것 같다.
// 스프링 컨테이너인 ApplicationContext 생성
ApplicationContext applicationContext
= new AnnotationConfigApplicationContext(AppConfig.class);
// 이 강의에서 구성 정보는 클래스는 AppConfig에 해당
ApplicationContext applicationContext
= new AnnotationConfigApplicationContext(AppConfig.class);
class ApplicationContextInfoTest {
AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("모든 빈 출력하기")
void findAllBean() {
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name = " + beanDefinitionName + " object = " + bean) ;
}
}
}
class ApplicationContextInfoTest {
AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("애플리케이션 빈 출력하기")
void findApplicationBean() {
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
// Role ROLE_APPLICATION: 직접 등록한 애플리케이션 빈
// Role ROLE_INFRASTRUCTURE: 스프링 내부에서 사용되는 빈
if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name = " + beanDefinitionName + " object = " + bean) ;
}
}
}
}
(예시 코드 양이 많아질 것 같아서 여기서부터는 예시 코드와 출력 결과는 생략...)
BeanFactory
ApplicationContext
ApplicationContext applicationContext
= new AnnotationConfigApplicationContext(AppConfig.class);
public class XmlAppContext {
@Test
void xmlAppContext() {
ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
MemberService memberService = ac.getBean("memberService", MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="memberService" class="hello.core.member.MemberServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository" />
</bean>
<bean id="memberRepository" class="hello.core.member.MemoryMemberRepository"/>
<bean id="orderService" class="hello.core.order.OrderServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository"/>
<constructor-arg name="discountPolicy" ref="discountPolicy"/>
</bean>
<bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy"/>
</beans>