해당 포스팅은 강좌를 보고 요약하고 실습을 따라가는 글이 적혀있습니다.
[스프링 핵심 원리 - 기본편 : 김영한] : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard
스프링 핵심 원리 - 기본편 - 인프런 | 강의
스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., 스프링 핵심 원리를 이해하고, 성장하는 개발자가 되어보세요! 📣 확인해주
www.inflearn.com
스프링 컨테이너 생성
- ApplicationContext를 스프링 컨테이너(인터페이스)라고 한다.
- 스프링 컨테이너를 만드는 방식
- XML 기반
- 현재와 같은 에노테이션 기반
- new AnnotationConfigApplicationContext(AppConfig.class)를 해주면 스프링 빈 저장소가 만들어진다.
- 스프링 컨테이너를 생성할 때는 구성정보를 지정해줘야하는데, 위 경우에는 AppConfig.class를 넘겨준다.
- 스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용하여 스프링 빈을 저장소에 등록한다.
- 빈 이름
빈 이름은 임의로 부여할 수도 있다. (@Bean(name = "memberBlah")
단, 항상 다른 이름으로 부여해야한다. - 다음으로 설정 정보를 참고하여 의존관계를 주입한다(DI)
** 참고 **
스프링은 빈을 생성하고 의존관계를 주입하는 단계가 나뉘어져있다.
내부적으로는 자바 코드로 스프링 빈을 등록하면 생성자를 호출하면서 의존관계 주입도 한번에 처리된다.
컨테이너에 등록된 모든 빈 조회
등록을 해둔 빈이 모두 다 제대로 등록됐는지 확인해보겠다.
Test에서 폴더와 파일을 만들어 확인해보았다.
내가 만든 것만 확인하기 위해 ROLE_APPLICATION인 것만 출력
5개 모두 잘 나온 것을 확인할 수 있다.
** 모든 빈 출력하기
- ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회한다.
- ac.getBean() : 빈 이름으로 빈 객체인스턴스를 조회
- 어플리케이션 빈 출력의 경우, getRole()을 사용하여
- ROLE_APPLICAION : 사용자가 정의한 빈
- ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈
스프링 빈 조회
- ac.getBean(빈이름, 타입)
- ac.getBean(타입)
- 빈이 없으면 예외 발생
NoSuchBeanDefinitionException: No bean named 'xxxxxx' available
구체 타입으로 조회하면 유연성이 떨어진다
스프링 빈 조회 - 동일한 타입이 둘 이상
- ac.getBeanOfType()을 사용하면 해당 타입의 모든 빈을 조회할 수 있다.
같은 타입으로 조회를 한다면? 에러가 난다.
그러므로, Type으로 조회를 할 때는 "이름"을 지정해주어야 한다.
하지만, 둘 다 꺼내고 싶다면 아래 처럼 하면 된다.
한번에 모두 조회하는 법은 후에 자동 주입에 사용될 수 있다.
스프링 빈 조회 - 상속 관계
빈을 조회할 때 부모와 자식의 관계로 되어있다면?
- 부모 타입으로 조회하면, 부모 타입을 포함하여 자식 타입도 함께 조회된다.
- 그래서 모든 자바 객체의 최고 부모인 Object 타입으로 조회하면 모든 스프링 빈을 조회한다.
- 부모 타입으로 조회 시, 자식이 둘 이상이면 중복 오류가 발생한다.
-> 빈 이름을 지정하면 된다
-> 특정(구체적인) 하위 타입으로 조회(좋은 방법은 아님) - ex) RateDiscountPolicy
-> 부모 타입으로 모두 조회하기 - ex) DiscountPolicy
-> ObjectType으로 조회하기 : spring 내부 빈까지 전부 다 꺼내짐
실제 개발할 때 빈을 조회하지 않지만,
순수한 java Application에서 Spring container를 생성할 때 사용하며,
자동 주입 시 사용되기 때문에 '한번에 조회하는 법' 등을 알아야한다.
BeanFactory와 ApplicationContext
BeanFactory
- 스프링 컨테이너의 최상위 인터페이스
- 스프링 빈을 관리하고 조회하는 역할 (getBean())
- 지금까지 우리가 사용한 대부분의 기능이 포함되어있음
ApplicationContext
- BeanFactory를 상속받아 추가 기능을 제공
- 둘의 차이?
어플리케이션을 개발할 때 빈을 관리/조회 기능은 물론이고, 수 많은 부가 기능이 필요하다.
- 메시지소스를 활용한 국제화 기능
한국에서 들어오면 한국어로 출력, 영어권에서 들어오면 영어로 출력 - 환경변수
로컬, 개발(테스트 서버), 운영(실제 프로덕션) 등을 구분해서 처리 - 어플리케이션 이벤트
이벤트를 발행하고 구독하는 모델을 편리하게 지원 - 편리한 리소스 조회
파일, 클래스 패스, 외부 등에서 리소스를 쓸 때 편리하게 조회할 수 있게 기능을 제공
BeanFactory를 그대로 사용하는 일은 거의 없고, 부가기능이 포함된 ApplicationContext를 사용한다.
또한 BeanFactory와 ApplicationContext를 모두 스프링 컨테이너라고 한다.
다양한 설정 형식 지원 - 자바 코드, XML
스프링 컨테이너는 자바코드, XML, Groovy 등 다양한 형식의 설정정보를 유연하게 받아들일 수 있게 설계되어있다.
XML 설정 사용
- 최근에는 스프링 부트를 사용하면서 XML 기반의 설정을 잘 사용하지 않는다.
- XML을 사용하면 컴파일 없이 빈 설정 정보를 변경할 수 있는 장점도 있다.
- GenericXmlApplicationContext를 사용하면서 xml 설정 파일을 넘기면 된다.
실행을 하면,
잘 되는 것을 알 수 있다.
이렇게 spring은 유연하게 설정 정보를 정할 수 있다.
스프링 빈 설정 메타 정보 - BeanDefinition
스프링은 어떻게 이렇게 다양한 형식을 지원할까?
정답은 BeanDefinition이라는 추상화 때문이다.
- XML을 읽어서 BeanDefinition을 만들면 된다.
- 자바 코드를 읽어서 BeanDefinition을 만들면 된다.
- 스프링 컨테이너는 자바 코드인지, XML인지 몰라도 된다. 오직 BeanDefinition(인터페이스)만 알면 된다.
BeanDefinition을 빈 설정 메타정보라 한다.
@Bean, <bean>당 각각 하나씩 메타 정보가 생성된다.
스프링 컨테이너는 이 메타정보를 기반으로 스프링 빈을 생성한다.
- AnnotationConfigApplicationContext 는 AnnotatedBeanDefinitionReader 를 사용해서 AppConfig.class 를 읽고 BeanDefinition 을 생성한다.
- GenericXmlApplicationContext 는 XmlBeanDefinitionReader 를 사용해서 appConfig.xml 설정 정보를 읽고 BeanDefinition 을 생성한다.
- 새로운 형식의 설정 정보가 추가되면, XxxBeanDefinitionReader를 만들어서 BeanDefinition 을 생성하면 된다.
<BeanDefinition>
실행을 해보면, 위와 같은 메타 정보들이 있다.
이러한 메타정보를 통해 직접 BeanDefinition을 생성할 수도 있지만, 실무에서 직접 정의하는 경우는 거의 없다.
BeanDefinition에 대해서는 너무 깊이 있게는 몰라도 되지만, 스프링이 다양한 형태의 설정 정보를 BeanDefinition으로 추상화해서 사용하는 것 정도만 이해하면 된다.
가끔 스프링 코드나 스프링 관련 오픈 소스의 코드를 볼 때, BeanDefinition 이라는 것이 보일 때가 있다. 이때 이러한 메커니즘을 떠올리면 된다.
'Web > Springboot' 카테고리의 다른 글
스프링 핵심 원리 - 기본 3] 객체 지향을 적용한 Spring 프로젝트 (0) | 2021.09.07 |
---|---|
스프링 핵심 원리 - 기본 2] Spring으로 간단한 프로젝트 만들어보기 (0) | 2021.09.07 |
스프링 핵심 원리 - 기본 1] 스프링을 시작해보자 (0) | 2021.09.07 |