-
Spring[3] Spring Container와 Spring bean개인 공부/spring 2021. 5. 15. 11:48728x90반응형
Spring 적용해보기
- AppConfig Spring 기반으로 변경
@Configuration public class AppConfig { @Bean public MemberService memberService() { return new MemberServiceImpl(memberRepository()); } @Bean public MemberRepository memberRepository() { return new MemoryMemberRepository(); } }
기존의 AppConfig 파일을 Spring annotation을 사용하여 Spring Container로 등록합니다.
- Spring Container란
- ApplicationContext를 Spring Container라 부릅니다.
- AppConfig에서 개발자가 직접 객체를 생성하고 DI를 했지만 이제는 Spring Container가 대신 해줍니다.
- @Configuration이 붙은 AppConfig의 정보를 사용하고 @Bean이 붙은 메서드를 호출해서 사용할 수 있습니다. 또한 @Bean이 붙은 메서드들을 스프링 빈이라 부릅니다.
- 스프링 빈으로 등록한 메서들은 아래와 같이 AnnotationConfigApplicationContext 메서드로 AppConfig.class 파일을 등록해주고 AppConfig에 설정해놓은 DI들을 이름으로/타입으로 조회할 수 있습니다.
public class ApplicationContextBasicFindTest { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); @Test @DisplayName("빈 이름으로 조회") void findBeanByName(){ MemberService memberService = ac.getBean("memberService", MemberService.class); assertThat(memberService).isInstanceOf(MemberServiceImpl.class); } @Test @DisplayName("타입으로 조회") void findBeanByType(){ MemberService memberService = ac.getBean(MemberService.class); assertThat(memberService).isInstanceOf(MemberServiceImpl.class); } @Test @DisplayName("구체 타입으로 조회") void findBeanByName2(){ MemberService memberService = ac.getBean("memberService",MemberServiceImpl.class); assertThat(memberService).isInstanceOf(MemberServiceImpl.class); } //test는 항상 실패 test까지 @Test @DisplayName("빈 이름으로 조회X") void findBeanByNameX(){ assertThrows(NoSuchBeanDefinitionException.class, () -> ac.getBean("XXXXX", MemberService.class)); } }
- 스프링 빈 조회하기
- ac는 위 예시코드의 변수명입니다.
- ac.getBean(빈이름, 타입)
- ac.getBean(타입)
- 위 두 방법으로 조회가 가능하지만 타입은 추천하지 않는다.
- NoSuchBeanDefinitionException == 조회할 수 없는 빈일 경우 예외 발생
- 동일한 타입이 2개 이상 있는 스프링 빈 조회하기
- ac.getBeansOfType()을 사용하면 해당 타입의 모든 빈이 조회 가능합니다.
- ac.getBean(타입)으로 2개 이상이 존재하는 빈을 조회할시 NoUniqueBeanDefinitionException 예외처리가 발생합니다.
- ac.getBean(빈이름, 타입)으로 조회하면 예외가 터질일이 없습니다.
- 스프링 빈의 상속관계
- 스프링 빈의 부모타입으로 조회하면 자식타입도 함께 조회됩니다.
- java 객체의 최고 부모인 Object로 조회하면 모든 스프링 빈을 조회할 수 있습니다.
BeanFactory
- BeanFactory란
- 스프링 컨테이너의 최상위 인터페이스입니다.
- 스프링 빈을 관리하고 조회하는 역할을 담당합니다.
- getBean()을 제공하는 곳입니다.
ApplicationContext
- ApplicationContext란
- BeanFoctory를 기능을 상속받아 제공합니다.
- BeanFoctory의 빈 조회, 관리 기능 뿐만 아니라 다른 부가기능을 지원합니다.
- ApplicationContext 지원 기능
- MessageSource
- 한국에서는 한국어, 영어권에서는 영어 사이트를 제공할 수 있도록 소스를 나눌수 있다.
- EnvironmentCapable
- 환경변수를 로컬, 개발, 운영등으로 구분하여 나눌수 있도록 처리해준다.
- ApplicationEventPublisher
- 이벤트를 발행하고 구독하는 모델을 편리하게 지원한다.
- ResourceLoader
- 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회할 수 있도록 지원한다.
- MessageSource
- 스프링 빈의 메타 정보
- 스프링 빈의 정보를 어디서 관리하는 것일까? Spring Container에서 등록을 하고 관리한다고 알고는 있지만 java로 spring을 설정하기도 하고 xml로 설정하기도 하며 json으로도 설정할 수 있습니다. 그렇다면 이 정보를 어떻게 spring에서 동일하게 처리해줄 수 있는걸까요?
- BeanDefinition이라는 추상화가 있기 때문에 가능
- 스프링 빈의 메타 정보 확인하기
public class BeanDefinitionTest { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext (AppConfig.class); @Test @DisplayName("빈 설정 메타정보 확인") void findApplicationBean() { String[] beanDefinitionNames = ac.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName); if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) { System.out.println("beanDefinitionName" + beanDefinitionName + " beanDefinition = " + beanDefinition); } } } }
위 코드를 실행시
위와 같이 Bean의 메타 정보를 확인할 수 있습니다.
- 스프링 빈의 메타 정보 내용
- BeanClassName: 생성할 빈의 클래스 명(자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
- factoryBeanName: 팩토리 역할의 빈을 사용할 경우 이름, 예) appConfig
- factoryMethodName: 빈을 생성할 팩토리 메서드 지정, 예) memberService
- Scope: 싱글톤(기본값)
- lazyInit: 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때 까지 최대한 생성을 지연처리 하는지 여부
- InitMethodName: 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명
- DestroyMethodName: 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
- Constructor arguments, Properties: 의존관계 주입에서 사용한다. (자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
728x90반응형'개인 공부 > spring' 카테고리의 다른 글
spring[5] ComponentScan과 Component (0) 2021.05.16 Spring[4] Spring의 Singleton Container (0) 2021.05.15 spring[2] Spring을 사용하지 않은 Java Web Project (0) 2021.05.14 MVC 패턴 (0) 2021.05.10 Spring[1] spring과 객체지향 (0) 2021.05.09