[Spring] 스프링 빈 조회
스프링 빈을 조회하는 다양한 방법에 대해 코드로 살펴보자. * BeanFactory BeanFactory는 스프링 컨테이너의 최상위 인터페이스 스프링 빈을 관리하고 조회하는 역할을 담당한다. getBean() 메서드를 제
supreme-ys.tistory.com
이 전 포스팅에 대한 답에 대한 포스팅이다.
스프링은 xml이나 annotation을 통해 빈을 등록할 수 있다. 빈을 등록할 때 스프링은 어떤 구조로 되어있길래 종류에 상관없이 빈을 등록할 수 있는지가 질문이었다. 그에 대한 답은 BeanDefinition에서 찾을 수 있다.
BeanDefinition은 추상화이다. 역할과 구현을 개념적으로 나눈 것인데, BeanDefinition은 Xml을 읽거나, 자바 코드를 읽든 BeanDefinition을 만들면 된다. 따라서, 스프링 컨테이너는 자바 코드인지, XML인지 몰라도 된다. 오직 BeanDefinition만 알면된다.
@Bean(어노테이션), <bean>(xml)당 각각 하나씩 메타 정보가 생성되며, BeanDefinition을 빈 설정 메타정보라고 한다.
스프링 컨테이너는 이런 메타정보를 기반으로 스프링 빈을 생성하게 된다.
이 전 포스팅에서 AnnotationConfigApplicationContext는 AnnotatedBeanDefinitionReader를 사용해서 AppConfig.class를 읽고 BeanDefinition을 생성한다.
이와 마찬가지로 xml또한, GenericXmlApplicationContext는 XmlBeanDefinitionReader를 사용해서 appConfig.xml설정 정보를 읽고 BeanDefinition을 생성한다.
즉, 새로운 형식의 설정 정보가 추가되면, ---BeanDefinitionReader를 만들어서 BeanDefinition을 생성하면 된다.
간단하게 테스트 코드를 통해 어떤 메타 정보들이 생성되는지 파악해보자!
public class BeanDefinitionTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("빈 설정 메타정보 확인")
void findApplicationBean() {
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
System.out.println("beanDefinitionName = " + beanDefinitionName +
" beanDefinition = " + beanDefinition);
}
}
}
}
beanDefinitionName = appConfig beanDefinition = 중략
beanDefinitionName = memberService beanDefinition = 중략
beanDefinitionName = orderService beanDefinition = 중략
beanDefinitionName = memberRepository beanDefinition = 중략
beanDefinitionName = discountPolicy beanDefinition = Root bean: 중략
package practice.spring.core;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import practice.spring.core.discount.DiscountPolicy;
import practice.spring.core.discount.RateDiscountPolicy;
import practice.spring.core.member.MemberRepository;
import practice.spring.core.member.MemberService;
import practice.spring.core.member.MemberServiceImpl;
import practice.spring.core.member.MemoryMemberRepository;
import practice.spring.core.order.OrderService;
import practice.spring.core.order.OrderServiceImpl;
/**
* @Configuration : 설정을 구성한다는 뜻의 어노테이션
* @Bean : 스프링 컨테이너에 빈(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();
// 이런식으로 "구성 영역"에서 바꿔만 주면 된다.
return new RateDiscountPolicy();
}
}
AppConfig에서 등록한 4가지 메서드와 1개의 AppConfig 설정 정보를 담은 클래스가 빈으로 등록된 것을 알 수 있다. 총 5가지!
'Programming > Spring' 카테고리의 다른 글
[MVC] HTML, HTTP API, CSR, SSR (0) | 2022.06.20 |
---|---|
[MVC] 동시요청 - 멀티쓰레드 (Multi-Thread) (0) | 2022.06.07 |
[Spring] 스프링 빈 조회 (0) | 2022.02.07 |
[Spring] ApplicationContext, 스프링 컨테이너, 스프링 빈(Bean) (0) | 2022.02.06 |
[스프링의 정석] HTTP 요청과 응답 (0) | 2021.10.28 |