김영한 스프링 핵심 원리 - 기본편 정리
목차
- 스프링 컨테이너 생성
- 컨테이너에 등록된 모든 빈 조회
- 스프링 빈 조회 - 기본
- 스프링 빈 조회 - 동일한 타입이 둘 이상
- 스프링 빈 조회 - 상속 관계
- BeanFactory와 ApplicationContext
- 다양한 설정 형식 지원 - 자바 코드, XML
- 스프링 빈 설정 메타 정보 BeanDefinition
스프링 컨테이너
- 스프링에서 자바 객체들을 관리하는 공간
- 자바 객체 = 스프링 빈(Bean)
- 빈의 생성부터 소멸까지 관리한다.
스프링 컨테이너 생성
// 스프링 컨테이너 생성
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
- ApplicationContext
- 스프링 컨테이너
- 인터페이스다. -> 다형성이 적용되어있다.
- 스프링 컨테이너는 XML 기반으로 만들 수 있고, 어노테이션 기반의 자바 설정 클래스로 만들 수 있다.
- 직전의 AppConfig를 사용한 방식이 어노테이션 기반의 자바 설정 클래스로 스프링 컨테이너를 만든 것.
- 자바 설정 클래스 기반으로 스프링 컨테이너를 만드는 것이 위의 코드 (new ~) 다.
이 클래스는 ApplicationContext 인터페이스의 구현체다.
스프링 컨테이너 생성 과정
1. 스프링 컨테이너 생성
- 스프링 컨테이너 생성시 구성 정보를 지정해주어야 한다.
- 여기서 AppConfig.class가 구성 정보다.
2. 스프링 빈 등록
- 스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해 스프링 빈을 등록한다.
- @Bean 이 붙어있는 것을 모두 호출한다.
- 메서드 이름 -> 빈 이름
- 메서드 이름 사용
- 빈 이름을 직접 부여할 수 도 있다.
ex) @Bean(name="memberService2") - 빈 이름은 항상 다르게 부여해야한다. (key로 생각)
- 무시, 덮어쓰기, 설정에 따라 오류가 발생할 수 있다.
- 메서드 호출로 생성된 객체 -> 빈 객체
3. 스프링 빈 의존관계 설정 - 준비
4. 스프링 빈 의존관계 설정 - 완료
- 스프링 컨테이너는 설정 정보를 참고해 의존관계를 주입(DI) 한다.
- 단순히 자바 코드를 호출하는 것 같지만, 차이가 있다.
이 차이는 뒤의 싱글톤 컨테이너에서 설명한다.
+++
스프링은 빈을 생성하고, 의존관계를 주입하는 단계가 나누어져 있다.
그런데 자바 코드로 스프링 빈을 등록하면, 생성자를 호출하며 의존관계 주입도 한 번에 처리된다.
자세한건 의존관계 자동 주입에서
컨테이너에 등록된 모든 빈 조회
스프링 컨테이너의 스프링 빈 출력
- 모든 빈 출력하기
- 실행시 스프링에 등록된 모든 빈 정보 출력 가능
- 빨간 박스 이외는 스프링이 내부적으로, 자체적으로 확장하기 위해 사용하는 것
- 빨간 박스 밑의 4개가 직접 등록한 것
ac.getBeanDefinitionNames(); // 스프링에 등록된 모든 빈 이름 조회
ac.getBean(); // 빈 이름으로 빈 객체(인스턴스) 조회
- 애플리케이션 빈 출력하기
- 스프링 내부에서 사용하는 빈은 제외하고, 내가 등록한 빈만 출력해보자.
- 스프링이 내부에서 사용하는 빈은 'getRole()'로 구분 가능
- ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
- ROLE_INFRASTRUCURE : 스프링이 내부에서 사용하는 빈
스프링 빈 조회 - 기본
- ac.getBean(빈이름, 타입)
- ac.getBean(타입)
- 조회 대상 스프링 빈이 없으면 예외 발생
- NoSuchBeanDefinitionException: No bean named 'xxxx' available
예제 코드
- 구체적인 타입으로 조회가 가능하지만 좋지 못하다.
- 변경시 유연성이 떨어지기 때문이다.
- 항상 실패 테스트를 만들어라!!!
스프링 빈 조회 - 동일한 타입이 둘 이상
- 타입으로 조회시 같은 타입의 스프링 빈이 둘 이상이면 오류 발생
- 이 때는 빈 이름을 지정해야 한다.
- ac.getBeansOfType()을 사용하면 해당 타입의 모든 빈을 조회할 수 있다.
예제 코드
스프링 빈 조회 - 상속 관계
- 부모 타입으로 조회하면, 자식 타입도 함께 조회한다.
- 그래서 모든 자바 객체의 최고 부모인 'Object' 타입으로 조회하면, 모든 스프링 빈을 조회한다.
예제 코드
- RateDiscountPolicy()로 하지 않는 이유
- 역할과 구현을 구분하기 위해서다.
BeanFactory와 ApplicationContext
BeanFactory
- 스프링 컨테이너의 최상위 인터페이스
- 스프링 빈을 관리하고 조회하는 역할을 담당
- getBean() 제공
- 지금까지 우리가 사용한 대부분의 기능은 BeanFactory가 제공하는 기능
ApplicationContext
- BeanFactory 기능을 모두 상속 받아 제공한다.
- 빈을 관리하고 검색하는 기능을 BeanFactory가 제공해주는데 무슨 차이?
-> 애플리케이션을 개발할 땐, 빈을 관리하고 조회는 물론 수 많은 부가기능이 필요하다.
-> 따라서 편리한 부가 기능을 제공한다.
ApplicationContext가 제공하는 부가기능
- 메시지 소스를 활용한 국제화 기능 : 한국에선 한국어, 영어권에선 영어로 출력
- 환경 변수 : 로컬, 개발, 운영 등을 구분해 처리
- 애플리케이션 이벤트 : 이벤트를 발행하고 구독하는 모델을 편리하게 지원
- 편리한 리소스 조회 : 파일, 클래스 패스, 외부 등에서 리소스를 편리하게 조회
BeanFactory나 ApplicationContext를 스프링 컨테이너라 한다.
BeanFactory를 직접 사용할 일은 거의 없고, 주로 부가기능이 포함된 ApplicationContext를 사용한다.
다양한 설정 형식 지원 - 자바 코드, XML
스프링 컨테이너는 다양한 형식의 설정 정보를 받아드릴 수 있게 유연하게 설계되어 있다.
- Java 코드, XML, Grooby 등
애노테이션 기반 자바 코드 설정 사용
- 지금까지 한 것
XML 설정 사용
- 최근 스프링 부트를 많이 사용하며 XML 기반 설정은 잘 사용 안 함.
레거시 프로젝트들이 XML로 되어있고, 컴파일 없이 빈 설정 정보 변경이 가능한 장점 때문에 배우는 것도 괜찮다. - GenericXmlApplicationContext 사용하며 xml 설정파일을 넘기면 된다.
*** xml 기반의 appConfig.xml 스프링 설정 정보와 자바 코드로 된 AppConfig.java 설정 정보를 비교해보면 거의 비슷하다.
스프링 빈 설정 메타 정보 BeanDefinition
- BeanDefinition이라는 추상화 덕에 스프링은 다양한 설정 형식을 지원한다.
- 쉽게 말해, 역할과 구현을 개념적으로 나눈 것이다.
- XML이든, 자바 코드든 읽어서 BeanDefinition을 만들면 된다.
- 스프링 컨테이너는 뭘로 구현됐는지 몰라도 된다. BeanDefinition만 알면 된다.
- BeanDefinition : 빈 설정 메타 정보
- @Bean, <bean> 당 각 하나씩 메타 정보가 생성된다.
- 스프링 컨테이너는 메타 정보를 기반으로 스프링 빈을 생성한다.
- 코드 레벨로 깊이있게 들어가고프다면 pdf 봐라
BeanDefinition 정보
BeanClassName | 생성할 빈의 클래스 명 (자바 설정처럼 팩토리 역할의 빈을 사용하면 없다.) |
factoryBeanName | 팩토리 역할의 빈을 사용할 경우 이름 ex) appConfig |
factoryMethodName | 빈을 생성할 팩토리 메소드 지정 ex) memberService |
Scope | 싱글톤 (기본값) |
lazyInit | 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아닌, 실제 빈을 사용할 때까지 최대한 생성을 지연처리 하는지 여부 |
InitMethodName | 빈을 생성하고, 의존관계 적용 뒤 호출되는 초기화 메서드 명 |
DestroyMethodName | 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명 |
Constructor arguments, Properties |
의존관계 주입에 사용한다. (자바 설정 처럼 팩토리 역할의 빈을 사용하면 없다.) |
- BeanDefinition을 직접 생성해 스프링 컨테이너에 등록할 수도 있다.
하지만, 실무에서 직접 정의하거나 사용할 일은 거의 없다. - 스프링이 다양한 형태의 설정 정보를 BeanDefinition으로 추상화해서 사용한다 정도로 이해해라.
'프로그래밍 > Spring' 카테고리의 다른 글
[Spring boot] 6. 컴포넌트 스캔 (0) | 2023.06.02 |
---|---|
[Spring boot] 5. 싱글톤 컨테이너 (0) | 2023.05.29 |
[Spring boot] 3. 스프링 핵심 원리 이해2 - 객체 지향 원리 적용 (0) | 2022.12.21 |
[Spring boot] 2. 스프링 핵심 원리 이해1 - 예제 만들기 (0) | 2022.12.15 |
[Spring Boot] 1. 객체 지향 설계와 스프링 (0) | 2022.11.11 |