스프링 컨테이너와 빈
정확히는 스프링 컨테이너를 부를때 BeanFactory, ApplicationContext 두개로 구분해서 설명한다.
BeanFactory를 직접 사용하는 경우는 거의 없음으로, ApplicationContext를 일반적으로
스프링 컨테이너라고 부른다.
빈은 메서드 이름을 사용할 수 있다.
빈 이름을 직접 부여할 수도 있다.
하지만 항상 다른 이름을 사용하자 만약 이름이 같다면 덮어버리면서 오류가 생길 수 있다.
무조건 단순하고 명확하게 개발해야 한다.
최근, Spring Boot 같은 경우 충돌이 생기면 default로 주의를 주며 스프링이 종료된다.
@Configuration
public class AppConfig {
@Bean
private static MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
private static DiscountPolicy discountPolicy() {
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
}
이전 글에서 작성한 코드의 일부분이다.
여기서 @Bean 으로 맵핑된 메서드들이 스프링 빈에 등록될 것이다.
스프링은 빈을 생성하고, 의존 관계를 주입하는 단계가 나누어져 있다. (후에 설명)
컨테이너에 등록된 모든 빈 조회
스프링 컨테이너에 등록된 빈을 확인해보자.
// 모든 빈 확인하는 Test Code
package hello.core.beanfind;
import hello.core.AppConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ApplicationContextInfoTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("모든 빈 출력")
void findAllBean() {
// getBeanDefinitionNames = 빈 네임(key) array로 반환.
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
// iter
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name = " + beanDefinitionName + " | object = " + bean);
}
}
}
위 코드로 빈을 출력했을때의 결과값을 확인해보자
name = org.springframework.context.annotation.internalConfigurationAnnotationProcessor | object = org.springframework.context.annotation.ConfigurationClassPostProcessor@3f9342d4
name = org.springframework.context.annotation.internalAutowiredAnnotationProcessor | object = org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@ab7395e
name = org.springframework.context.annotation.internalCommonAnnotationProcessor | object = org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@50d13246
name = org.springframework.context.event.internalEventListenerProcessor | object = org.springframework.context.event.EventListenerMethodProcessor@2bd08376
name = org.springframework.context.event.internalEventListenerFactory | object = org.springframework.context.event.DefaultEventListenerFactory@e70f13a
name = appConfig | object = hello.core.AppConfig$$SpringCGLIB$$0@3d3e5463
name = memberRepository | object = hello.core.member.MemoryMemberRepository@64a40280
name = discountPolicy | object = hello.core.discount.RateDiscountPolicy@4b40f651
name = memberService | object = hello.core.member.MemberServiceImpl@42b02722
name = orderService | object = hello.core.order.OrderServiceImpl@d62fe5b
상위 5개는 스프링에서 자동으로 등록시킨 빈이며,
appConfig 부터 아래 5개의 빈이 AppConfig를 통해 등록시킨 스프링 빈의 목록이다.
아래는 내가 등록한 빈만 확인할 수 있는 테스트 코드이다
package hello.core.beanfind;
import hello.core.AppConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ApplicationContextInfoTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("Application 빈 출력")
void findApplicationBean() {
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
// BeanDefinition.ROLE_APPLICATION = 직접 등록한 빈
// BeanDefinition.INFRASTRUCTURE = 스프링이 등록한 빈
if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name = " + beanDefinitionName + " | object = " + bean);
}
}
}
}
반응형
'BackEnd' 카테고리의 다른 글
[DB] 효율적인 설계를 위해 어떤 SQL을 사용해야 할까? RDBMS vs NoSQL과 DB에서의 수직 확장(scale-up)과 수평 확장(scale-out) (0) | 2024.06.20 |
---|---|
[Spring] 스프링이 사랑한 디자인 패턴 - 1 (0) | 2024.05.29 |
[Spring] BeanFactory와 ApplicationContext 이해하기 (0) | 2024.04.03 |
[Spring] 스프링 핵심원리 - 기본편 / 관심사의 분리 (0) | 2024.04.01 |
Python으로 백엔드 서버 아주쉽게 구축하기 (Flask 서버) (0) | 2023.10.10 |