2000년대 초반 - java 진영의 대표 표준기술, 스프링 및 JPA를 합친 기능들 가진EJB(Enterprise Java Beans)를 사용했음. But EJB는 시간이 오래 걸리고 복잡했음..
-> Spring, Hibernate 등장
-> Hibernate가 표준 JPA기술의 원형이 됨.
현재: JPA라는 표준 인터페이스를 하이버네이트와 같은 JPA구현체를 통해 구현, 이용한다.
Spring은 여러 기술들의 모음이다.
필수
스프링 프레임워크 : 스프링 기술의 핵심임.
스프링 부트 : 여러 스프링 기술을 편리하게 사용하도록 도와줌
선택
스프링 데이터 : 데이터베이스의 기본적인 CRUD 편리하게 사용할 수 있도록 도와준다.
스프링 세션 : 세션을 편리하게 사용할 수 있도록 도와준다.
스프링 시큐리티 : 보안 관련
스프링 Rest Docs : API 문서화 편리하게 도와줌
스프링 배치 : 배치 처리에 특화된 기술
스프링 클라우드 : 클라우드에 특화된 기술
핵심 기술: 스프링 DI 컨테이너, AOP, 이벤트, 기타
웹 기술: 스프링 MVC, 스프링 WebFlux
데이터 접근 기술: 트랜잭션, JDBC, ORM 지원, XML 지원
기술 통합: 캐시, 이메일, 원격접근, 스케줄링
테스트: 스프링 기반 테스트 지원
언어: 코틀린, 그루비
최근에는 스프링부트를 통해서 스프링 프레임워크의 기술들을 편리하게 사용한다.
스프링을 편리하게 사용할 수 있도록 지원, 최근에는 기본으로 사용한다.
단독으로 실행할 수 있는 스프링 애플리케이션을 귑게 생성해준다.
Tomcat같은 웹 서버를 내장해서 별도의 웹 서버를 설치하지 않아도 된다.
-> 스프링부트가 빌드하고 서버에 띄우는 것까지 알아서 해준다.
손쉬운 빌드 구성을 위한 starter 종속성 제공
-> 스프링에서 필요한 라이브러리들을 가져와준다.
스프링과 3rd parth(외부) 라이브러리 자동 구성
-> 현재 사용중인 스프링 프레임워크의 버전에서 사용할 수 있는 외부 라이브러리의 버전을 자동으로 구성해준다.
메트릭, 상태 확인, 외부 구성 같은 프로덕션 준비 기능 제공
-> 운영 환경에서 모니터링을 위한 기능 제공 등
관례에 의한 간결한 설정
-> 꼭 필요할 때만 커스터마이징 하면 됨
스프링이라는 단어는 문맥에 따라 다르게 사용된다.
이 기술을 왜 만들었는가? 핵심 컨셉은?
역할과 구현을 분리
-> 변경이 용이
- 다형성의 본질
인터페이스를 구현한 객체 인스턴스르 실행 시점에 유연하게 변경할 수 있다.
클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다.
역할과 구현의 분리 - 한계
역할(인터페이스) 자체가 변하면, 클라이언트와 서버 모두에 큰 변경이 발생.
따라서 인터페이스를 안정적으로 잘 설계하는 것이 중요하다 !
객체 지향의 꽃은 다형성 !
스프링은 다형성을 극대화해서 이용할 수 있게 도와준다.
스프링에서의 제어의 역전(IoC), 의존관계 주입(DI)은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원한다.
-> 마치 레고 블럭 조립하듯이 구현을 편리하게 변경할 수 있다.
- SRP: 단일 책임 원칙(single responsibility principle)
- OCP: 개방-폐쇄 원칙(Open/closed principle)
- LSP: 리스코프 치환 원칙(Liskov substitution principle)
- ISP: 인터페이스 분리 원칙(Interface segregation principle)
- DIP: 의존관계 역전 원칙(Dependency inversion principle)
가장 중요한 원칙 !
소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다.
다형성을 활용
<문제점>
MemberService 클라이언트가 구현 클래스를 직접 선택
• MemberRepository m = new MemoryMemberRepository(); //기존 코드
• MemberRepository m = new JdbcMemberRepository(); //변경 코드
구현 객체를 변경하려면 클라이언트 코드를 변경해야 한다. -> 다형성 사용했지만 OCP 원칙 지킬 수 X... -> ??
어떻게 해결 ? -> 객체를 생성하고 연관관계를 맺어주는 별도의 조립, 설정자가 필요하다 ! 그것이 바로 스프링 컨테이너가 해주는 역할.
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
인터페이스가 명확해지고, 대체 가능성이 높아진다.
그런데 OCP에서 설명한 MemberService는 인터페이스에 의존하지만, 구현 클래스도
동시에 의존한다.
• MemberService 클라이언트가 구현 클래스를 직접 선택
• MemberRepository m = new MemoryMemberRepository();
• DIP 위반
스프링은 다음 기술로 다형성 + OCP, DIP를 가능하게 지원한다.
- DI - 의존관계, 의존성 주입
- DI 컨테이너 제공
-> 클라이언트 코드의 변경 없이 기능 확장 + 쉽게 부품 교체하듯이 개발