스프링 빈

LST·2022년 7월 25일
0

스프링 컨테이너의 생성

ApplicationContext ac =
	new AnnotationConfigApplicationContext(AppConfig.class);
  • ApplicationContext를 스프링 컨테이너라고 하고, 이것은 인터페이스이다.
  • Annotation~ 은 ApplicationContext 의 구현체이다.
  • 어노테이션 기반으로 스프링 컨테이너를 만드는 구현체도 있고, xml기반으로 스프링 컨테이너를 만드는 구현체도 있다.(GenericXmlApplicationContext)

스프링 컨테이너의 생성 과정

스프링 컨테이너는 빈을 생성하고, 의존관계를 주입하는 두가지 단계가 나누어져있다. 하지만 생성자 주입을 하면 생성자 호출과 동시에 의존관계 주입도 한번에 처리된다.

  1. 스프링 컨테이너 생성
    • new AnnotationConfigApplicationContext(AppConfig,class) 를 통해 컨테이너를 생성한다.
    • 스프링 컨테이너를 생성할 때는 구성 정보를 지정해주어야 하는데 여기서는 AppConfig.class를 구성정보로 지정했다.
    • 스프링 컨테이너에 스프링 빈 저장소를 만든다.
  1. 스프링 빈 등록
    • 스프링 컨테이너는 파라미터로 넘어온 구성정보를 사용해서 스프링 빈을 등록한다.
    • 빈 이름은 기본적으로 메소드 이름을 사용하지만, 이름을 직접 부여할 수 도 있다. ( @Bean(name="newName") )
    • 빈 이름은 항상 다른 이름을 부여해야 한다. 같은 이름이 부여되면, 다른 빈이 무시되거나, 기본 빈을 덮어버리거나 하는 오류가 발생한다.
  1. 의존관계 설정
    • 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입한다.

스프링 컨테이너 빈 조회

  • 컨테이너의 모든 빈 출력
String[] beans = ac.getBeabDefinitionNames();
for(String beanName : beans){
    Object bean = ac.getBean(beanName);
    System.out.println(bean);
}
  • 빈 종류별로 출력
BeanDefinition beanDefinition = ac.getBeanDefinition(beanName);
//ROLE_APPLICATION 직접 등록한 빈
//ROLE_INFRASTRUCTURE 스프링이 내부에서 사용하는 빈
if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION){
	Object bean = ac.getBean(beanName);
    System.out.println(bean);
}
  • 빈 이름으로 조회
MemberService memberService = ac.getBean("memberService",MemberService.class);

ac.getBean(이름, 타입)으로 빈을 조회할 수 있지만 이전의 코드에선 ac.getBean(이름) 으로 출력을 했다. 이것의 차이점은 getBean(이름)으로 사용시 Object 타입이 반환되기 때문에 타입캐스팅을 해줘야 한다.

MemberService memberService = ac.getBean("memberService"); // 타입오류
Object object = ac.getBean("memberService"); // 정상작동
MemberService memberService = (MemberService) ac.getBean("memberService"); // 타입 캐스팅을 해야한다
  • 빈 타입으로 조회
MemberService memberService = ac.getBean(MemberService.class);
  • 빈 타입으로 조회 시 같은 타입이 둘 이상일 경우 오류가 발생한다.
assertThrows(NoUniqueBeanDefinitionException.class,
	()->ac.getBean(MemberRepository.class));
  • 빈 타입으로 모두 조회
Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);
for (String key : beansOfType.keySet()) {
	System.out.println("key = "+ key + " value = "+beansOfType.get(key));
}
  • 부모 타입으로 조회
// 부모타입으로 조회 시 자식타입도 함께 조회된다. 
// 자식이 여러개일경우 에러가 발생한다. 
assertThrows(NoUniqueBeanDefinitionException.class, 
	() ->ac.getBean(DiscountPolicy.class));
// 부모타입으로 모두 조회하기
Map<String, DiscountPolicy> beansOfType = ac.getBeansOfType(DiscountPolicy.class);
for(String key : beansOfType.keySet()){
	System.out.println(beansOfType.get(key));
}

0개의 댓글