섹션4. 스프링 핵심 원리 이해2 - 객체 지향 원리 적용 <= 마무리
섹션5. 스프링 컨테이너와 스프링 빈
이렇게 공부를 했습니다.
섹션4. 스프링 핵심 원리 이해2 - 객체 지향 원리 적용
저번주에 듣고 남은 부분을 마무리했습니다.
(7) 좋은 객체 지향 설계의 5가지 원칙의 적용
여기서 3가지 SRP, DIP, OCP를 적용했다.
① SRP(단일 책임 원칙): 한 클래스는 하나의 책임만 가져야 한다.
- 구현 객체를 생성하고 연결하는 책임은 AppConfig가 담당한다.
- 클라이언트 객체는 실행하는 책임만 담당한다.
② DIP(의존관계 역전 원칙): 추상화에 의존해야지, 구체화에 의존하면 안된다. 의존성 주입도 이 원칙을 따른다.
- 기존 클라이언트 코드는 구현 클래스에도 함께 의존했었다.
- AppConfig가 객체 인스턴스를 클라이언트 코드 대신 생성해 의존관계를 주입해주어 문제를 해결했다.
③ OCP: 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
- 애플리케이션을 사용 영역과 구성 영역으로 나눴기 때문에, 소프트웨어 요소를 새롭게 확장해도 사용 영역의 변경은 닫혀 있다.
(8) IoC, DI, 그리고 컨테이너
① IoC(제어의 역전)
- 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것을 제어의 역전이라 한다.
- 프로그램에 대한 제어 흐름에 대한 권한은 모두 AppConfig가 가지고 있다. 구현 객체는 자신의 로직을 실행하는 역할만 담당한다. 예를 들어서 OrderServiceImpl 은 필요한 인터페이스들을 호출하지만 어떤 구현 객체들이 실행될지 모른다.
cf) 프레임워크: 내가 작성한 코드를 제어하고, 대신 실행한다.
라이브러리: 내가 작성한 코드가 직접 제어의 흐름을 담당한다.
② DI(의존관계 주입)
두 가지 의존관계로 나누어볼 수 있다.
1) 정적인 클래스 의존관계
- 정적인 의존관계는 애플리케이션을 실행하지 않아도 분석할 수 있다.
2) 동적인 객체 인스턴스 의존관계
- 애플리케이션 실행 시점에 실제 생성된 객체 인스턴스의 참조가 연결된 의존 관계다.
- 의존관계 주입: 애플리케이션 실행 시점에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결되는 것을 말한다.
- 의존관계 주입을 사용하면 정적인 클래스 의존관계를 변경하지 않고, 동적인 객체 인스턴스 의존관계를 쉽게 변경 할 수 있다.
③ 컨테이너
- AppConfig처럼 객체를 생성하고 관리하면서 의존관계를 연결해 주는 것을 IoC 컨테이너 또는 DI 컨테이너라 한다.
(9) 스프링으로 전환하기
- @Bean 을 붙여주면 스프링 컨테이너에 스프링 빈으로 등록한다는 뜻이다.
- ApplicationContext는 스프링 컨테이너를 말한다. 스프링 컨테이너는 @Configuration이 붙은 AppConfig를 설정(구성) 정보로 사용한다.
- 이때 @Bean이라 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라 한다.
- 스프링 빈은 @Bean이 붙은 메서드의 명을 스프링 빈의 이름으로 사용한다.
섹션5. 스프링 컨테이너와 스프링 빈
(1) 스프링 컨테이너 생성
- ApplicationContext를 스프링 컨테이너라고 하고, 이는 인터페이스다.
- 스프링 컨테이너는 애노테이션 기반의 자바 설정 클래스 또는 XML을 기반으로 만들 수 있다. 직전에 AppConfig를 사용했던 방식은 애노테이션 기반의 자바 설정 클래스로 스프링 컨테이너를 만든 것이다.
- AnnotationConfigApplicationContext는ApplicationContext 인터페이스의 구현체이다.
- 구성 정보로 AppConfig.class을 지정했다.
스프링 컨테이너의 생성 과정은 이러하다.
1) 스프링 컨테이너 생성
2) 스프링 빈 등록
- 빈 이름은 메서드 이름 또는 직접 부여할 수 있다.
- 이때 빈 이름은 항상 다른 이름을 부여해야 한다.
3) 스프링 빈 의존관계 설정 - 준비
4) 스프링 빈 의존관계 설정 - 완료
- 스프링에서는 빈을 생성하고, 의존관계를 주입하는 단계가 나누어져 있다.
- 반대로 자바 코드에서는, 스프링 빈을 등록하면 생성자를 호출하면서 의존관계 주입도 한번에 처리된다.
(2) 컨테이너에 등록된 모든 빈 조회
1) 모든 빈 출력하기
- ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회한다.
- ac.getBean() : 빈 이름으로 빈 객체(인스턴스)를 조회한다.
2) 애플리케이션 빈 출력하기
- 스프링이 내부에서 사용하는 빈은 getRole() 로 구분할 수 있다.
- ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
(3) 스프링 빈 조회 - 기본
스프링 컨테이너에서 스프링 빈을 찾는 방법
- ac.getBean(빈이름, 타입)
- ac.getBean(타입)
- 조회 대상 스프링 빈이 없으면 예외 발생한다. NoSuchBeanDefinitionException 발생.
cf) 구체 타입으로 조회하면 변경시 유연성이 떨어진다.
(4) 스프링 빈 조회 - 동일한 타입이 둘 이상
- 타입으로 조회시 같은 타입의 스프링 빈이 둘 이상이면 오류가 발생한다. 이때는 빈 이름을 지정해야 한다.
- ac.getBeansOfType() 을 사용하면 해당 타입의 모든 빈을 조회할 수 있다.
(5) 스프링 빈 조회 - 상속 관계
- 부모 타입으로 조회하면, 자식 타입도 함께 조회한다. 그래서 모든 자바 객체의 최고 부모인 Object 타입으로 조회하면, 모든 스프링 빈을 조회한다.
(6) BeanFactory와 ApplicationContext
BeanFactory나 ApplicationContext를 스프링 컨테이너라 한다.
- BeanFactory
- 스프링 컨테이너의 최상위 인터페이스
- 스프링 빈을 관리하고 조회하는 역할
- ApplicationContext
- BeanFactory의 기능을 상속받는다.
- 빈 관리기능 + 편리한 부가 기능 제공
(7) 다양한 설정 형식 지원 - 자바 코드, XML
스프링 컨테이너는 다양한 형식의 설정 정보를 받아들일 수 있게 유연하게 설계되어 있다.
xml 기반의 appConfig.xml 스프링 설정 정보와 자바 코드로 된 AppConfig.java 설정 정보를 비교해보면 거의 비슷하다는 것을 알 수 있다.
(8) 스프링 빈 설정 메타 정보 - BeanDefinition
- BeanDefinition: 빈 설정 메타정보
- 스프링 컨테이너는 이 메타정보를 기반으로 스프링 빈을 생성한다.
'WINK-(Web & App) > Spring Boot 스터디' 카테고리의 다른 글
[2025 1학기 스프링부트 스터디] 오세웅 #3주차 (0) | 2025.04.10 |
---|---|
[2025 1학기 스프링부트 스터디] 최비성 #2주차 (0) | 2025.04.09 |
[2025 1학기 스프링부트 스터디] 남윤찬 #3주차 (0) | 2025.04.08 |
[2025 1학기 스프링부트 스터디] 류현준 #2주차 (0) | 2025.04.08 |
[2025 1학기 스프링 부트 스터디] 석준환 #3주차 (0) | 2025.04.08 |