Spring Bean 이란?

Spring IoC 컨테이너가 관리하는 자바 객체를 Bean 이라고 한다. 즉, Spring에 의해서 생성되고 관리되는 자바 객체라고 한다. 

Spring Container 

Spring Container를 구성하는 ApplicationContext 다형성으로 구현된다. 여기에서 ApplicationContext가 인터페이스이고 AnnotationConfigApplicationContext 구현체가 된다. 만약에, 빈에 대한 설정정보를 AppConfig.class 에 등록해두면 이 정보를 보고 객체 생성을 하게 된다. 스프링 컨테이너는 (빈 이름 | 빈 객체)로 등록된다. 이러한 동적인 의존관계를 스프링이 설정해준다. 

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

스프링 컨테이너에서는 설정정보를 참조해 의존관계를 주입한다. 
ApplicationContext 에 등록된 빈은 아래 코드로 확인해 볼 수 있다. 

  • BeanDefinition.ROLE_APPLICATION : 사용자가 등록한 빈
  • BeanDefinition.ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈

아래와 같이 사용 예를 확인해볼 수 있다.

void findAllBean() {
	 String[] beanDefinitionNames = ac.getBeanDefinitionNames();
	 for (String beanDefinitionName : beanDefinitionNames) {
		 Object bean = ac.getBean(beanDefinitionName);
		 System.out.println("name=" + beanDefinitionName + " object=" +
		bean);
 	}
 }

Spring Bean을 찾을 때는 getBean(빈이름, 타입), getBean(타입)로 조회할 수 있다. 

※ getBean 에 타입을 등록할 때 인터페이스를 넣는것이 좋다. 구현 클래스가 들어가도 찾는데 문제는 없지만 코드의 유연성 목적을 위해 인터페이스를 넣는것이 좋다. 다만, 구현 클래스의 경우에는 Spring Container에 등록되어 있어야 한다. 

빈 타입에 대한 조회는 JUnit5의 Assertions.assertThrows 를 활용해서 확인해볼 수 있다. MemberService.class 타입을 확인하는 코드는 아래와 같다. 

@Test
@DisplayName("빈 이름으로 조회X")
 void findBeanByNameX() {
	 //ac.getBean("xxxxx", MemberService.class);
	 Assertions.assertThrows(NoSuchBeanDefinitionException.class, () ->
	ac.getBean("xxxxx", MemberService.class));
}

BeanFactory와 ApplicationContext

BeanFactory 최상위 인터페이스인데 빈을 관리하고 조회하는 역할을 수행한다. ApplicationContext 도 BeanFactory를 상속받아 제공하는데 BeanFactory와 다르게 여러 부가기능을 제공한다. 

  • MessageSource : ko → ko, en → en
  • EnvironmentCapable : 로컬, 개발, 운영 구분해서 처리
  • ApplicationEventPublisher : 이벤트를 발행하고 구독하는 모델
  • ResourceLoader : 파일, 클래스 패스, 외부 등에서 리소스를 조회

XML 으로 설정

Spring Container는 여러 형식의 설정 정보를 받아들일 수 있도록 유연하게 설계되어 있다. 컴파일 없이 빈 설정 정보를 변경할 수 있는 장점이 있다. 아래 코드와 XML가 동일한 역할을 수행한다.

//class
private final MemberRepository memberRepository;
 public MemberServiceImpl(MemberRepository memberRepository) {
 this.memberRepository = memberRepository;
 }
 
 
//xml
<bean id="memberService" class="hello.core.member.MemberServiceImpl">
 <constructor-arg name="memberRepository" ref="memberRepository" />
 </bean>
 <bean id="memberRepository"
class="hello.core.member.MemoryMemberRepository" />

BeanDefinition

빈 설정 관련된 메타정보가 포함되어 있다. 여기에 scope, lazyInit, autowired 가 포함된다. 이러한 메타정보를 기반으로 인스턴스를 생성된다. 객체지향으로 보면 역할과 구현을 나눠볼 수 있는데 Spring Container는 BeanDefinition에만 의존하기 때문에 AppConfig.class, .xml에 신경쓰지 않아도 된다. Bean을 구현하는 방법은 XML을 쓸 수 도 있고 Java Class 를 이용해서 Factory Method를 통해서 구현할 수 있다. 

'IT' 카테고리의 다른 글

테스트 방법  (0) 2023.03.18
캐시방법  (0) 2023.03.11
카프카 스터디를 시작하며  (0) 2022.12.03
넥스트스텝 - 레이싱 카 2단계  (0) 2022.01.30
넥스트스텝 - 레이싱 카 1단계  (0) 2022.01.29