Today I Learned

2024 스파르타 내일배움캠프 Sping 트랙 참여 // day30

shinelee26 2024. 11. 12. 22:13

오늘 진행한 학습 요약

1. Spring 숙련 - 1주차

  • 객체 지향 설계
    • SOLID 원칙
    • Spring과 객체 지향
  • Spring의 핵심 개념
    • Spring Container
    • Spring Bean
  • IOC/DI
    • IOC(제어의 역전, Inversion Of Control)
    • DI(의존성 주입, Dependency Injection)
  • Singleton Pattern
    • 싱글톤 패턴(Singleton Pattern)
    • 싱글톤 패턴의 주의점
  • Spring Bean 등록
    • @ComponentScan
    • @Configuration, @Bean
    • Bean 충돌
    • @Qualifier, @Primary
    • 수동 VS 자동
  • 의존관계 주입
    • 의존관계 주입
    • 생성자 주입
    • @RequiredArgsConstructor
  • Validation
    • 검증(Validation)
    • BindingResult
  • Bean Validation
    • Bean Validation
    • Field Error
    • Validator
    • 에러 메세지
    • Object Error
    • Bean Validation의 충돌
    • groups
    • groups VS DTO 분리
    • @ModelAttribute, @RequestBody

2. Spring 개념 정리

  • 의존성 주입 정리
  • Spring Bean 정리
  • @Validated 정리

3. 알고리즘 코드카다  Day28(작성 생략)

CodingTest Git-hub 링크 : https://github.com/chews26/CodingTest

 


학습 정리

1. Spring 숙련 - 1주차

 

객체 지향 설계

  • SOLID 원칙
    • 단일 책임 원칙 SRP(Single Responsibility Principle)
      • 하나의 클래스는 하나의 책임만 가져야 한다.
    • 개방 폐쇄 원칙 OCP(Open Closed Principle)
      • 소프트웨어 요소는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 한다.
    • 리스코프 치환 원칙 LSP(Liskov Substitution Principle)
      • 자식 클래스는 언제나 부모 클래스를 대체할 수 있어야 한다.
    • 인터페이스 분리 원칙 ISP(Interface Segregation Principle)
      • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
    • 의존관계 역전 원칙 DIP(Dependency Inversion Principle)
      • 구체적인 클래스에 의존하지 말고, 인터페이스나 추상 클래스에 의존하도록 설계해야 한다.
  • Spring과 객체 지향
    • Spring은 다형성 만으로는 해결하지 못했던 객체 지향 설계 원칙 중 OCP, DIP를 IOC, DI를 통해 가능하도록 만들어준다.

Spring의 핵심 개념

  • Spring Container
    • Spring으로 구성된 애플리케이션에서 객체(Bean)를 생성, 관리, 소멸하는 역할을 담당
    • 애플리케이션 시작 시, 설정 파일이나 Annotation을 읽어 Bean을 생성하고 주입하는 모든 과정을 컨트롤
    • 주방의 Chef → 재료 선택, 요리, 완성까지 모든 것을 관리
    • Spring Container의 종류
      • BeanFactory
        • Spring Container의 최상위 인터페이스
        • Spring Bean을 관리하고 조회
      • ApplicationContext
        • BeanFactory의 확장된 형태(implements)
        • Application 개발에 필요한 다양한 기능을 추가적으로 제공
        • 국제화, 환경변수 분리, 이벤트, 리소스 조회
  • Spring Bean
    • Spring 컨테이너가 관리하는 객체를 의미
    • 자바 객체 자체는 특별하지 않지만, Spring이 이 객체를 관리하는 순간부터 Bean이 된다
    • Spring은 Bean을 생성, 초기화, 의존성 주입 등을 통해 관리
    • Chef인 Spring Container가 요리할 음식에 사용될 재료(Bean)
    • Spring 컨테이너에 의해 생성되고 관리
    • 기본적으로 Singleton으로 설정
    • 의존성 주입(DI)을 통해 다른 객체들과 의존 관계
    • 생성, 초기화, 사용, 소멸의 생명주기
    • XML, Java Annotation, Java 설정파일 등을 통해 Bean으로 등록

IOC/DI

  • IOC(제어의 역전, Inversion Of Control)
    • 객체의 생성과 관리 권한을 개발자가 아닌 Spring 컨테이너가 담당
    • Spring에서는 컨테이너가 객체 생성, 주입, 소멸을 관리
    • 요리사(개발자)는 필요한 재료를 직접 준비하지 않고, Chef가 알아서 필요한 재료(Bean)을 관리하고 요리사에게 가져다준다.
    • 객체 간의 결합도를 낮춰 유연한 코드
    • IoC는 객체의 제어권을 개발자가 아닌 Spring 컨테이너에게 넘기는 개념으로, Spring이 객체 생성과 관리를 담당
  • DI(의존성 주입, Dependency Injection)
    • Spring이 객체 간의 의존성을 자동으로 주입해주는 것을 의미
    • 한 객체가 다른 객체를 사용할 때, 해당 객체를 직접 생성하지 않고 Spring이 주입해주는 방식
    • IOC를 구현하는 방식 중 하나
    • 셰프가 요리를 만들 때 필요한 재료(Bean)를 자동으로 요리사에게 가져다주는 과정으로 요리사(개발자)는 재료를 찾을 필요 없이, Chef가 알아서 제공해준다.
    • DI는 Spring이 객체 간의 의존성을 자동으로 주입해주는 기법

Singleton Pattern

  • 싱글톤 패턴(Singleton Pattern)
    • 클래스의 인스턴스가 오직 하나만 생성되도록 보장하는 디자인 패턴
    • 객체 인스턴스가 하나만 생성되고 생성된 인스턴스만 사용
    • 싱글톤 패턴을 구현하기 위한 코드의 양이 많다
    • 구현 클래스에 의존해야 한다.(DIP, OCP 위반)
    • Spring Container는 싱글톤 패턴의 문제점들을 해결하면서 객체를 싱글톤으로 관리
  • 싱글톤 패턴의 주의점
    • 객체의 인스턴스를 하나만 생성하여 공유하는 싱글톤 패턴의 객체는 상태를 유지(stateful)하면 안된다.
      • 상태 유지(stateful)의 문제점
        • 데이터의 불일치나 동시성 문제가 발생할 수 있다
      • Spring Bean은 항상 무상태(stateless)로 설계를 해야한다. 아주 중요!

Spring Bean 등록

  • @ComponentScan
    • Spring이 특정 패키지 내에서 @Component, @Service, @Repository, @Controller 같은 Annotation이 붙은 클래스를 자동으로 검색하고, 이를 Bean으로 등록하는 기능
    • Bean을 직접 등록하지 않고도 Spring이 자동으로 관리할 객체들을 찾는다.
    • Chef가 요리할 재료를 자동으로 식료품 저장고에서 찾아오는 과정, Chef는 스스로 필요한 재료를 찾아 요리에 사용한다. 요리사(개발자)가 직접 재료(Bean)를 찾아서 가져올 필요가 없다.
    • @ComponentScan의 동작 순서
      • 1. Spring Application이 실행되면 @ComponentScan이 지정된 패키지를 탐색
      • 2. 해당 패키지에서 @Component 또는 Annotation이 붙은 클래스를 찾음
      • 3. 찾은 클래스를 Spring 컨테이너에 빈으로 등록
      • 4. 등록된 빈은 의존성 주입(DI)과 같은 방식으로 다른 빈과 연결
  • @Configuration, @Bean
    • Spring Bean을 등록하는 방법에는 수동, 자동 두가지가 존재
      • 자동 Bean 등록(@ComponentScan, @Component)
      • 수동 Bean 등록(@Configuration, @Bean)
  • Bean 충돌
    • Bean 등록 방법에는 수동, 자동 두가지가 존재하고 Bean은 각각의 이름으로 생성된다. 이때 이름이 같은 Bean이 설정되고자 한다면 충돌이 발생
  • @Qualifier, @Primary
    • 같은 타입의 Bean이 중복된 경우 해결하기 위해 사용하는 Annotation
    • @Autowired + 필드명 사용
      • 타입으로 먼저 주입을 시도하고 같은 타입의 Bean이 여러개라면 필드 이름 혹은 파라미터 이름으로 매칭
    • @Qualifier 사용
      • Bean 등록 시 추가 구분자 붙임
      • 생성자 주입, setter 주입 사용 가능
    • @Primary 사용
      • @Primary로 지정된 Bean이 우선 순위를 가짐
  • 수동 VS 자동
    • Annotation 기반의 Spring에서는 자동 Bean 등록과 의존관계 주입을 사용하는 경우를 주로 사용
    • 자동 Bean 등록을 사용하는 이유
      • 다양한 Annotation으로 편리하게 등록
      • Spring Boot는 ComponentScan 방식을 기본으로 사용
      • 간단하지만 OCP, DIP를 준수하며 개발
    • 수동 Bean 등록을 사용하는 경우
      • 외부 라이브러리나 객체를 Spring Bean으로 등록
      • 데이터베이스 연결과 같이 비지니스 로직을 지원하는 기술들에 사용
      • 같은 타입의 Bean 여러개 중 하나를 명시적으로 선택해야 할 때

의존관계 주입

  • 의존관계 주입
    • 의존관계 주입을 하는 방법으로 생성자 주입, setter 주입, 필드 주입, 메서드 주입 총 4가지 방법이 존재
    • 1. 생성자 주입
      • 생성자를 통해 의존성을 주입하는 방법.
      • 최초에 한번 생성된 후 값이 수정되지 못한다.[불변, 필수]
    • 2. Setter 주입
      • Setter 메서드를 통해 의존성을 주입하는 방법.
    • 3. 필드 주입
      • 필드에 직접적으로 주입하는 방법 (가장 추천되지 않음).
      • 코드는 간결하지만 Spring이 없으면 사용할 수 없다.
    • 4. 일반 메서드 주입
      • 생성자, setter 주입으로 대체가 가능하기 때문에 사용하지 않는다.
  • 생성자 주입
    • 생성자 주입을 선택하는 이유
      • 어떤 요리(Web Application)를 만들지 정해졌다면 이미 재료(Bean)와 의존 관계가 결정된다.
      • 객체를 생성할 때 최초 한번만 호출된다.(불변)
      • setter 주입을 사용하면 접근제어자가 public 으로 설정되어 누구나 수정할 수 있게된다.
      • 순수 Java 코드로 사용할 때(주로 테스트 코드) 생성자의 필드를 필수로 입력하도록 만들어준다.(NPE 방지)
      • 컴파일 시점에 오류를 발생 시킨다. 즉, 실행 전에 오류를 알 수 있다.
  • @RequiredArgsConstructor
    • Web Application을 개발하면 대부분이 불변 객체이고 생성자 주입 방식을 선택
    • 이런 반복되는 코드를 편안하게 작성하기 위해 Lombok에서 제공하는 Annotation
    • @RequiredArgsConstructor
      • final 필드를 모아서 생성자를 자동으로 만들어 주는 역할
      • Annotation Processor 가 동작하며 컴파일 시점에 자동으로 생성자 코드를 만들어줌
      •  

Validation

  • 검증(Validation)
    • 특정 데이터(주로 클라이언트의 요청 데이터)의 값이 유효한지 확인하는 단계를 의미
      • 식당 메뉴판(specification)에 있는 메뉴만 주문이 가능하다. 안내를 통해 제대로된 주문을 받을 수 있다.
    • 검증의 종류
      • 프론트 검증
      • 서버 검증
      • 데이터베이스 검증
  • BindingResult
    • Spring에서 기본적으로 제공되는 Validation 오류를 보관하는 객체
    • 주로 사용자 입력 폼을 검증할 때 많이 쓰이고 Field Error와 ObjectError를 보관
    • Errors 인터페이스를 상속받은 인터페이스
    • Errors 인터페이스는 에러의 저장과 조회 기능을 제공
    • BindingResult는 addError() 와 같은 추가적인 기능을 제공
    • Spring이 기본적으로 사용하는 구현체는 BeanPropertyBindingResult

Bean Validation

  • Bean Validation
    • 특정 필드 검증의 경우 빈값, 길이, 크기, 형식 과 같은 간단한 로직
    • 이러한 로직들을 모든 프로젝트에 적용할 수 있도록 표준화 한 것이 Bean Validation
    • Bean Validation은 기술 표준 인터페이스
    • 다양한 Annotation들과 여러가지 Interface로 구성
    • Bean Validation(인터페이스) 구현체인 Hibernate Validator를 사용
    • Hibernate Validator 공식문서 :  https://hibernate.org/validator/ 
    • 버전별 공식 메뉴얼 : https://docs.jboss.org/hibernate/validator
  • Field Error
    • 의존성 추가(build.gradle)
      • implementation 'org.springframework.boot:spring-boot-starter-validation'
    • External Libraries
      • 파일경로 jakarta.validation-api-${version}.jar
    • jakarta.validation.constraints
      • 사용할 수 있는 다양한 Annotation들을 확인
    • Annotation 들이 동작하게 만들어주는 Validator
      • 파일경로 org.hibernate.validator:hibernate-validator:${version}
    • jakarta.validation-api : Interface
    • org.hibernate.validator:hibernate-validator : 구현체
  • Validator
    • 단순히 Annotation을 선언해주면 검증이 완료되는 이유는 Validator(Validation을 사용하는것)가 존재하기 때문
    • Spring Boot는 validation 라이브러리를 설정하면 'org.springframework.boot:spring-boot-starter-validation'자동으로 Bean Validator를 Spring에 통합되도록 설정
    • @Valid, @Validated 차이점
      • @Valid 는 JAVA 표준
      • @Validated 는 Spring 에서 제공하는 Annotation
  • 에러 메세지
    • Spring의 Bean Validation은 Default로 제공하는 Message들이 존재하고 임의로 수정할 수 있음
      • Error Message
      • Bean Validation을 적용하고 BindingResult에 등록된 검증 오류를 확인해보면 오류가 Annotation 이름으로 등록
      • 에러 메세지 수정하기
        • NotNull.Object.fieldName  
        • NotNull.fieldName(MessageSource)
        • NotNull.FieldType(MessageSource)
        • NotNull
  • Object Error
    • 필드 단위가 아닌 객체 전체에 대한 오류
    • 두 필드 간의 관계를 검증할 때 ObjectError를 통해 해당 오류를 BindingResult에 기록할 수 있음
    • Object Error는 로직으로 구현하면 됨
    • 1. @ScriptAssert
    • 2. Java 코드로 구현
  • Bean Validation의 충돌
    • 등록, 수정 API에서 각각 다른 Validation이 적용된다면?
      • HTTP 요청은 사용자가 임의로 변경하여 요청할 수 있음으로 항상 서버에서 최종적으로 추가 검증을 진행 해야함
      • 저장할 Object를 직접 사용하지 않고 SaveRequestDto, UpdateRequestDto 따로 사용
  • groups
    • Bean Validationgroups 속성은 다양한 유효성 검사 시나리오를 정의할 때 사용
    • 동일한 객체에 대한 검증을 상황에 따라 다르게 적용하고 싶을 때 groups를 활용
  • groups VS DTO 분리
    • Bean Validation의 충돌이 발생하는 경우 대부분 DTO를 분리하는 방법이 적절
  • @ModelAttribute, @RequestBody
    • @Valid, @Validated@ModelAttribute뿐만 아니라 @RequestBody에도 적용
    • @ModelAttribute는 요청 파라미터 혹은 Form Data(x-www-urlencoded)를 다룰 때 사용
    • @RequestBody 는 HTTP Body Data를 Object로 변환할 때 사용

 

2. Spring 개념 정리

  • 의존성 주입 정리
 

의존성 주입 | Notion

스프링 부트에서 의존성 주입은 객체 간의 연결을 자동으로 설정해주는 방식이에요. 예를 들어, A 클래스가 B 클래스의 기능을 사용해야 한다고 해볼게요. 보통은 A 클래스 안에서 B를 직접 생성

shinelee26.notion.site

  • Spring Bean 정리
 

Spring Bean | Notion

Spring에서 **Bean(빈)**은 Spring IoC (Inversion of Control) 컨테이너가 관리하는 객체를 의미합니다. 즉, Spring이 애플리케이션을 실행할 때 필요에 따라 생성하고, 의존성을 주입하며, 필요한 시점에 제공

shinelee26.notion.site

 

  • @Validated 정리
 

@Validated | Notion

@Validated 어노테이션은 Spring Framework에서 제공하는 유효성 검사(Validation)를 위한 어노테이션입니다. 주로 컨트롤러나 서비스 계층에서 메서드 파라미터나 객체의 유효성을 검증할 때 사용됩니다.

shinelee26.notion.site