🔸 ApplicationContext 인터페이스를 스프링 컨테이너라 한다.
🔸 XML기반, 어노테이션 기반으로 자바 설정 클래스를 만들 수 있다.
🔸 BeanFactory, ApplicationContext로 구분할 수 있다.ApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
- 스프링 컨테이너 생성
new AnnotationConfigApplicationContext(AppConfig.class);
- 스프링 컨테이너는 내부에 빈 저장소를 가지고 있는데 이 빈 저장소는 빈 이름(key)과 빈 객체(value)로 구성되어 있다.
- 지정된 구성설정정보(파라미터로 받은 AppConfig.class)를 활용해서 스프링 빈을 등록한다.
(@Bean이 붙은 것 모두 호출해서 빈 저장소에 저장)- 설정 정보를 참조해서 의존관계를 주입한다.
🔸 빈을 직접 등록하는 경우에는 생성하고 의존관계를 주입하는 단계가 한번에 처리된다
@Configuration public class AppConfig{ @Bean public MemberService memberService(){ return new MemberRepository(memberRepository); }
🔸 하지만 자동으로 등록하는 경우에는 생성과, 의존관계 주입의 단계가 나누어서 진행된다.
ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회 ac.getBean(빈이름, 타입) : 빈 이름, 타입으로 빈 객체(인스턴스)를 조회 ➡️ 조회대상 빈이 없으면 NoSuchBeanDefinitionException 발생 * ac.getBean("memberService", MemberServiceImpl.class); ➡️ 구체 타입으로 조회할 수도 있지만, 변경 시 유연성이 떨어진다. (추상화(역할)에 의존하는 것이 아닌 구현에 의존하는 것.)
🔸 NoUniqueBeanDefinitionException 발생
void findBeanByName(){ MemberRepository memberRepository = ac.getBean("memberRespository1", MemberRepository.class); } ➡️ 같은 타입의 빈이 여러 개 있을 경우, 빈 이름을 지정해 줘야 한다.
🔸 특정 타입을 모두 조회하기
void findAllBeanByType(){ Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class); for(String key : beansOfType.keySet()){ System.out.println("key = " + key + ", value = " + beansOfType.get(key)); } System.out.println("beansOfType = " + beansOfType); }
🔸 부모타입으로 조회를 하면 자식타입도 함께 조회가 된다. ➡️ Object타입으로 조회하면 모든 스프링 빈을 조회한다.
🔸 자식이 둘 이상 있으면 NoUniqueDefinitionException 발생
➡️ 빈 이름을 지정하거나 특정 하위 타입으로 조회하면 된다.🔸 부모타입(Object)으로 모두 조회하기
void findAllBeanByObjectType() { Map<String, Object> beansOfType = ac.getBeansOfType(Object.class); for (String key : beansOfType.keySet()) { System.out.println("key = " + key + " value=" + beansOfType.get(key)); } }