Spring Container 생성
- ApplicationContext는 인터페이스(다형성)이며, 스프링 컨테이너라고 부른다.
- AppConfig를 사용했던 방식을 애노테이션 기반의 자바 설정 클래스로 스프링 컨테이너를 만든 것이다.
- new AnnotationConfigApplicationContext(AppConfig.class); 는 ApplicationContext인터페이스의 구현체이다.
- 스프링 컨테이너는 (BeanFactory, ApplicationContext)로 구분할 수 있다. 일반적으로 ApplicationContext 사용한다.
- 스프링 컨테이너 생성 시 구성 정보(AppConfig)를 입력해야 한다.
Spring Bean 등록
- @Bean 애노테이션을 사용해 각 메서드에 붙여주면 Bean이 등록된다.
- 빈 이름 = 메서드 명 / 빈 객체 = return 되는 객체명
- @Bean(name="choonsik" 이와 같이 이름을 변경할 수 있으나 원래 메서드명 사용을 가급적 추천하고, 빈 이름이 중복되지 않도록 주의한다. 중복될 경우 기존 빈 값을 덮어쓰거나 오류를 발생시킬 수 있다.
- 자바 코드로 스프링 빈을 등록하면, 생성자를 호출하는 것과 동시에 의존관계 주입도 한번에 처리된다.
등록된 Bean 조회
beanDefinitionName = org.springframework.context.annotation.internalConfigurationAnnotationProcessorobject = org.springframework.context.annotation.ConfigurationClassPostProcessor@2e61d218
beanDefinitionName = org.springframework.context.annotation.internalAutowiredAnnotationProcessorobject = org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@3569fc08
beanDefinitionName = org.springframework.context.annotation.internalCommonAnnotationProcessorobject = org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@20b12f8a
beanDefinitionName = org.springframework.context.event.internalEventListenerProcessorobject = org.springframework.context.event.EventListenerMethodProcessor@e84a8e1
beanDefinitionName = org.springframework.context.event.internalEventListenerFactoryobject = org.springframework.context.event.DefaultEventListenerFactory@2e554a3b
beanDefinitionName = appConfigobject = hello.core.AppConfig$$EnhancerBySpringCGLIB$$ccc7ff19@54a67a45
beanDefinitionName = memberServiceobject = hello.core.member.MemberServiceImpl@7d42c224
beanDefinitionName = memberRepositoryobject = hello.core.member.MemoryMemberRepository@56aaaecd
beanDefinitionName = orderServiceobject = hello.core.order.OrderServiceImpl@522a32b1
beanDefinitionName = discountPolicyobject = hello.core.discount.FixDiscountPolicy@35390ee3
- 1~10줄은 스프링 내부에서 사용되는 빈
- 11~15줄은 내가 등록한 빈 (Config도 Bean으로 등록됨)
- 모든 빈을 출력할 때 ac.getBeanDefinitionName()을 사용하면 스프링에 등록된 모든 빈 이름을 조회
- ac.getBean()을 사용하면 빈 이름으로 빈 객체(인스턴스)를 조회한다.
Name = appConfigobject = hello.core.AppConfig$$EnhancerBySpringCGLIB$$ccc7ff19@2e61d218
Name = memberServiceobject = hello.core.member.MemberServiceImpl@3569fc08
Name = memberRepositoryobject = hello.core.member.MemoryMemberRepository@20b12f8a
Name = orderServiceobject = hello.core.order.OrderServiceImpl@e84a8e1
Name = discountPolicyobject = hello.core.discount.FixDiscountPolicy@2e554a3b
- 내가 등록한 애플리케이션 빈 출력
- 스프링에서 사용하는 빈 = getRole()
- 사용자가 등록한 빈 = ROLE_APPLICATION
- 스프링 내부에서 사용하는 빈 = ROLE_INFRASTRUCTURE
- (빈 이름 + 인터페이스 타입)으로 조회 가능
- (타입) 만으로 조회 가능 (같은 타입의 빈이 여러 개일 경우 에러 발생)
- (빈 이름 + 구현체 타입)으로 조회 가능
- 존재하지 않는 빈 이름으로 조회 (항상 예외도 테스트해볼 것) ⭐⭐⭐⭐
- 상속 관계에서 부모 타입을 조회하면 자식 빈들은 모두 조회된다. (자바의 최상위층 object타입 조회 -> 모든 빈 조회 )
BeanFactory
- 스프링 컨테이너의 최상위층 인터페이스
- 스프링 빈을 관리하고 조회하는 역할
- getBean() 제공
- 우리가 그동안 사용한 기능은 beanFactory가 제공하는 기능
ApplicationContext
- BeanFactory 기능을 모두 상속받아서 제공
- + 부가기능 가지고 있음
- MessageSource interface : 언어를 상황에 맞게 국제화
- EnvironmentCapable interface : 로컬, 개발, 운영을 구분해서 처리
- ApplicationEventPublisher interface : 이벤트를 발행하고 구독하는 모델을 편리하게 지원
- ResourceLoader : 파일, 클래스 패스, 외부 등에서 리소스를 편리하게 조회
BeanDefinition
beanDefinition = Generic bean: class [hello.core.AppConfig$$EnhancerBySpringCGLIB$$ccc7ff19]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=nullbeanDefinition = Generic bean: class [hello.core.AppConfig$$EnhancerBySpringCGLIB$$ccc7ff19]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
beanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=memberService; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfigbeanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=memberService; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfig
beanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=memberRepository; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfigbeanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=memberRepository; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfig
beanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=orderService; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfigbeanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=orderService; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfig
beanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=discountPolicy; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfigbeanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=discountPolicy; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfig
BeanDefinition 이란?
- BeanDefinition는 빈 설정 메타정보로 불림
- BeanDefinition이 스프링 빈 메타정보를 생성하고 스프링 컨테이너는 BeanDefinition에만 의존
- 스프링 컨테이너는 이 메타정보를 기반으로 스프링 빈을 생성
BeanDefinition 이 가지고 있는 정보
- BeanClassName : 생성할 빈의 클래스 명
- FactoryBeanName : 팩토리 역할의 빈을 사용할 경우 ex). AppConfig
- factoryMethodName : 빈을 생성할 팩토리 메서드 지정 ex). memberService
- Scope : (default) 싱글톤
- lazyInit : 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아닌, 실제 빈을 사용할 때까지 최대한 생성을 지연처리하는지 여부
- InitMethodName : 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드명
- DestroyMethodName : 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드명
- Constructor arguments, Properties : 의존관계 주입에서 사용
'IT 정보 > Spring' 카테고리의 다른 글
[Spring] AOP 기본 개념 (47) | 2022.06.21 |
---|---|
[Spring] 컴포넌트 스캔 (44) | 2022.06.20 |
[Spring] Bean Scope (Singleton pattern) (43) | 2022.06.16 |
[Spring] 스프링 컨테이너 (12) | 2022.06.16 |
[Spring] FrameWork (36) | 2022.06.15 |