[인프런|Spring] 스프링 핵심 원리 – 기본편
스프링 핵심 원리 – 기본편
객체 지향 설계와 스프링
이야기 - 자바 진영의 추운 겨울과 스프링의 탄생
- EJB ( Enterprise Java Beans ) 자바 표준 기술 중 최고봉
- 코드가 어렵고 복잡해서 지옥이라고 불림.
- 해결: 하이버네이트(JPA)와 스프링이라는 새로운 기술이 생김.
스프링의 역사
로드 존슨 책 출간 -> 오픈 소스 프로젝트 시작
스프링이란?
특정한 하나가 아니라 여러 개의 모음
- 필수: 스프링 프레임워크, 스프링 부트
- 선택: 스프링 데이터, 스프링 세션, 스프링 시큐리티, 스프링 Rest Docs, 스프링 배치, 스프링 클라우드
스프링 프레임워크
- 핵심기술 : 스프링 DI 컨테이너, AOP, 이벤트 기타
- 웹 기술: 스프링 MVC, 스프링 WebFlux
- 데이터 접근 기술: 트랜잭션, JDBC, ORM지원, XML 지원
- 기술 통합: 캐시, 이메일, 원격접근, 스케줄링
- 테스트: 스프링 기반 테스트 지원
- 언어: 코틀린, 그루비
스프링부트 : 스프링을 편리하게 사용할 수 있도록 지원
스프링의 핵심 개념 및 컨셉 : 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크
좋은 객체 지향 프로그래밍이란?
- 다형성 : 클라이언트에 영향을 주지 않고 새로운 기능을 추가할 수 있음.
- 유연하고 변경 가능하다
- 역할과 구현을 분리한다.
- 역할: 인터페이스, 구현: 인터페이스를 구현한 클래스와 구현 객체
- 자바의 다형성 : 오버라이딩
- 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다.
** 인터페이스를 잘 설계하는 것이 중요해진다.
좋은 객체 지향 설계의 5가지 원칙(SOLID)
- SRP : 단일 책임 원칙 (하나의 클래스는 하나의 책임만 가진다 – 변경이 있을 때, 파급효과가 작다면, 이 원칙이 잘 지켜진 코드이다.)
- OCP: 개방-폐쇄 원칙 (확장에는 열려 있으나 변경에는 닫혀 있어야한다.)
- LSP: 리스코프 치환 원칙 (하위 타입의 인스턴스로 바꿀 수 있어야한다.)
- ISP: 인터페이스 분리 원칙 (기능을 적당한 크기로 분리한다.)
- DIP: 의존관계 역전 원칙(추상화(역할)에 의존O, 구체화(구현)에는 의존X)
객체 지향 설계와 스프링
- 스프링, DI 컨테이너 제공: 의존관계 의존성 주입으로 OCP, DIP를 가능하게 함.
스프링 핵심 원리 이해1 – 예제 만들기
프로젝트 생성
- 스프링 부트 스타터로 스프링 프로젝트 생성
비즈니스 요구사항과 설계
회원 도메인 설계
- 회원을 가입하고 조회할 수 있다.
-
- 역할: 클라이언트, 회원 서비스, 회원 저장소
- 회원 저장소의 구현: 메모리, DB, 외부 시스템
- 회원 서비스 : MemberServiceImpl
회원 도메인 개발
회원 도메인 실행과 테스트
- Junit : @test 코드 작성
주문과 할인 도메인 설계
- 역할과 구현을 분리: 구현 객체를 조립할 수 있게 설계가 되었다.
- Enum type 은 비교문에 있어서 ==을 사용하는 것이 맞음.
주문과 할인 도메인 개발
주문과 할인 도메인 실행과 테스트
스프링 핵심 원리 이해2 - 객체 지향 원리 적용
새로운 할인 정책 개발
새로운 할인 정책 적용과 문제점
- 인터페이스에만 의존하도록 설계를 변경
관심사의 분리
- AppConfig의 등장 : 구현 객체를 생성하고 연결하는 책임은 따로 클래스를 만든다.
-
- 의존관계 주입
IoC, DI, 그리고 컨테이너
- 제어의 역전 : 내가 직접 호출하는 것이 아니라, 프레임워크가 내 코드를 실행해주는 것.
- AppConfig : 프로그램에 대한 제어 흐름에 대한 권한을 모두 가진다. Impl 클래스는 단순히 실행하는 역할만을 담당하고, AppConfig가 프로그램의 제어 흐름을 모두 가져간다.
프레임워크 vs 라이브러리
- 프레임워크 : 내가 작성한 코드를 대신 제어하고 대신 실행 (내가 필요한 부분만 개발함.)
- 라이브러리 : 내가 작성한 코드가 직접 제어한다.
의존 관계 주입
- 정적인 클래스 의존 관계 (실행 없이도 확인 가능)
- 실행 시점에 결정되는 동적인 객체 의존관계 ( 인스턴스 )
- 의존 관계 주입은 정적인 클래스 의존관계의 변함 없이 동적인 의존관계만 변경 가능하다는 장점이 있다.
IoC컨테이너 ( = DI컨테이너, 어셈블러, 오브젝트 팩토리 )
AppConfig처럼 의존 관계 주입을 해주고 제어 흐름을 담당하는 것을 의미한다.
스프링으로 전환하기
- AppConfig는 @Configuration 이고 하나하나의 함수는 @Bean이 된다.
- AppConfig를 사용하기 위해서는
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
OrderService orderService = applicationContext.getBean("orderService", OrderService.class);
로 사용한다.
- 기존에는 개발자가 직접 자바코드로 모든 것을 했다면 이제부터는 스프링 컨테이너에 객체를 스프링 빈으로 등록 하고, 스프링 컨테이너에서 스프링 빈을 찾아서 사용하도록 변경되었다.