22.04.05 WIL Spring & IoC & DI

Spring Framework의 핵심 개념 - 꼼꼼하게 숙지하고 공부하자!

  • Spring IoC 컨테이너 , Beans
  • 리소스 핸들링(Resource와 ResourceLoader)
  • Validation과 Data Binding, 타입 변환
  • 스프링 Expression 언어
  • AOP
  • Null - safety
  • 데이터 Buffer와 코덱
  • 로깅

용어 정리 - 용어에 대한 개념을 확실히 정립해 놓아야 한다!

DDD(Domain Driven Design)에서 사용되는 용어들

Domain ElementState/Behavior
엔터티, VO(값 객체), AggregateState and Behavior
DTO(Data Transfer Object)State Only
Service, RepositoryBehavior Only

Entity

다른 엔터티와 구별할 수 있는 식별자를 가지고 있고 시간의 흐름에 따라 지속적으로 변경이 되는 객체

Value Object

각 속성이 개별적으로 변화하지 않고 값 그 자체로 고유한 불변 객체

Aggregate

하나의 단위로 생각할 수 있는 객체들의 군집이다. Root Entity 와 다른 여러 Entity, Value Object 를 포함한다. 일반적으로 비지니스 Entity 들이 Aggregate 다. 예를 들면, Customer, Account, Order, Product 이다.

Aggregate 군집 내에서 ACID가 만족이 되어야 한다. 즉 Aggregate를 기준으로 Transaction 이 보장되어야 한다!

의존성과 결합도

의존성이란?

어떤 객체가 다른 객체를 필요로 할때 , 다른 객체와 협력할 때 의존성이 생기게 된다.

  • 컴파일타임 의존성 : 코드를 작성하는 시점에서 발생하는 의존성. 클래스 사이의 의존성
  • 런타임 의존성 : 어플리케이션이 실행되는 시점의 의존성. 객체 사이의 의존성

결합도란?

하나의 객체가 변경이 일어날 때 관계를 맺고 있는 다른 객체에게 변화를 요구하는 정도

의존성이 바람직하다면 → 느슨한 결합도 혹은 약한 결합도

의존성이 바람직하지 않다면 → 단단한 결합도 또는 강한 결합도

결합도가 높으면 요구사항 변경 시 한 클래스만 변경하면 되는 것이 아니라 의존되어있는 모든 클래스까지 변경해야 한다. 그러므로 우리는 결합도를 낮추는 것이 목표가 된다.

Inversion of Control(제어의 역전) - The Hollywood Principle

자바 어플리케이션이 개발된 초반에는 개발자가 제어권을 가지고 있어, 자바 객체를 생성하고 의존성 주입 등이 개발자가 직접 수행했다고 한다.

IoC는 이전의 방식과 다르게 클래스를 결정하고 해당 클래스 객체를 생성하는 작업을 사용하는 쪽에서 결정하는 것이 아니라, 프레임워크가 그 주도권을 가지게 함으로써 개발자가 만든 어플리케이션 코드를 사용하게 하는 방식을 말한다.
IoC 컨테이너에서는 개별 객체들의 의존관계 설정이 자동으로 이루어지고 객체들의 생성과 파괴 조합 등을 관장한다.

객체가 자신이 의존하고 있는 객체를 직접 생성하지 않게 하자! IoC 컨테이너와 같은 외부 클래스에서 객체를 주입함으로써 결합도를 줄일 수 있다.

  • 기본 상식 라이브러리와 프레임워크의 차이!
    • 라이브러리 : 주도권이 개발자에게 있다.
    • 프레임워크 : 주도권이 프레임워크에게 있다.

ApplicationContext(스프링 컨테이너)

Spring에서는 ApplicationContext 인터페이스를 제공함으로써 IoC 컨테이너를 제공한다.
ApplicationContext는 BeanFactory를 상속받는데 BeanFactory에서 IoC의 기본기능(객체에 대한 생성, 조합, 의존관계 설정)등을 제공한다.
여기서 객체들은 IoC 컨테이너가 관리하냐 안관리하는 객체이냐로 나뉘게되는데 이를 구분하기 위해서 IoC 컨테이너에 의해 관리되는 객체를 Bean이라고 한다.
ApplicationContext는 빈 관리기능(Bean Factory) + 부가기능들을 제공한다

부가기능

  • 메세지소스를 활용한 국제화 기능 - 한국에서 들어오면 한국어로, 영어권에서 들어오면 영어로 출력
  • 환경 변수 - 로컬, 개발, 운영 등을 구분해서 처리
  • 어플리케이션 이벤트 - 이벤트를 발행하고 구독하는 모델을 편리하게 지원
  • 편리한 리소스 조회 - 파일, 클래스패스, 외부 등에서 리소스를 편하게 조회

Configuration Metadata

Application은 Configuration Metadata(설정 메타데이터)를 통해 실제 만들어야 할 빈 정보들을 받고, 객체들을 생성하고 구성한다.

Configuration Metadata를 작성하는 방법

  • Java 파일 기반 - AnnotationConfigApplicationContext
  • XML 기반 - GenericXmlApplicationContext

어떻게 ApplicationContext는 두가지 방법 모두 지원할까? 추상화를 통해 구현할 수 있다.

BeanDefinition(빈 설정 메타 정보)

BeanDefinition 정보

  • BeanClassName : 생성할 빈의 클래스명
  • factoryBeanName : 팩토리 역할의 빈을 사용할 경우 이름(Ex appConfig)
  • factoryMethodName : 빈을 생성할 팩토리 메서드 지정 (Ex memberService)
  • Scope : Singleton, Prototype 등등
  • lazyinit : 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때 까지 최대한 생성을 지연처리 하는지 여부
  • InitMethodName : 빈을 생성하고, 의존관계를 적요한 뒤에 호출되는 초기화 메서드 명
  • DestroyMethodName : 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
  • Constructor arguments, Properties : 의존관계 주입에서 사용

    XML 기반, 자바 파일 기반 Configuration Metadata 모두 BeanDefinition으로 추상화할 수 있는데, 스프링 컨테이너는 XML인지, 자바인지 알 필요없이 오직 BeanDefinition만 알면 되기에 다양한 방법으로 메타데이터를 설정할 수 있는 것이다.

Dependency Injection(DI)

IoC는 전략패턴(Strategy Pattern), 서비스 로케이터 패턴(Service Locator Pattern), 팩토리 패턴(Factory Pattern) , 의존관게 주입패턴 등으로 만들수 있다.
그 중 생성자를 통해서 객체를 주입받는 패턴을 생성자 주입 패턴(Dependency Injection) 이라고 부른다.

추가 Java 14 Record

java 14 이전에는 불변 객체를 만드려면 클래스를 만들고, 불변을 만족하도록 필드와 메서드를 선언해야 했다.

이 과정에서 많은 실수들이 나올 수 있는데 Java 14부터는 record라는 것을 지원하면서 이 문제를 해결할 수 있게 하였다.

불변 객체를 만족하려면 다음과 같은 조건을 만족해야 한다.

쉽게 말하자면 클래스 내부의 필드들을 전부 private final로 선언하고, equals, hashcode, toString을 알맞게 재정의 해 줘야 한다.

불변 객체를 만들수록 위와 같은 표준 코드를 작성해야한다! 얼마나 불편한가?

JDK 14부터는 반복 데이터 클래스를 record 대체할 수 있다. 레코드는 필드의 유형과 이름만 필요로 하는 불변의 데이터 클래스이다.

//record 예시
public record Person (String name, String address{}

record는 불변객체를 만족하도록 constructor, equals, hashcode, toString을 알맞게 재정의해 주므로 단순히 불변객체만 필요하다면 위의 코드처럼 사용해도 될것이다.

Reference

aggregate란?

좋은 웹페이지 즐겨찾기