이 글은 김영한 님의 스프링 핵심 원리 - 기본편(https://www.inflearn.com/스프링-핵심-원리-기본편/dashboard)을 수강하며 학습한 내용을 정리한 글입니다. 모든 출처는 해당 강의에 있습니다.
개념
특징
장단점
장점 | 단점 |
---|---|
[인스턴스 풀링] ▪ 객체를 미리 생성 + 메모리에 저장 → 사용준비 상태로 전환 ▪ 많은 동시접속자에 대한 안정성 지원 | 객체지향적이지 않음 |
[트랜잭션 처리] ▪ 처리 메소드를 컨테이너가 트랜잭션 자동 처리 ▪ 안정적인 데이터 조작 가능 | 복잡한 프로그래밍 모델 |
[퍼시스턴스 관리] ▪ 빈즈의 상태를 메모리에서 사용 여부에 따라 자동으로 활성화/비활성화 실행하여 관리 | 특정 환경·기술에 종속적인 코드 |
FAT Client → Thin Client, n-tier(다층 구조) 시스템 구축 가능 | 컨테이너 안에서만 동작할 수 있는 객체 구조 |
▪ Weblogic, Websphere를 주로 사용 ▪ 국산은 제우스(jeus) 사용 | 자동화된 테스트가 매우 어렵거나 불가능 |
EJB 컴포넌트들이 Loading 되어 활동하는 서버 쪽 프로그램, 컴포넌트의 생성, 소멸, 라이프 사이클, 보안, Threading 등의 서비스 제공 | 부족한 개발생산성 및 이동성(portability) |
“우리는 사람들이 자기네 시스템에 보통의 객체를 사용하는 것을 왜 그렇게 반대하는지 궁금하였는데, 간단한 객체는 폼 나는 명칭이 없기 때문에 그랬던 것이라고 결론지었다. 그래서 적당한 이름을 하나 만들어 붙였더니, 아 글쎄, 다들 좋아하더라고.” — 마틴 파울러
EJB의 단점들로 인해 대표적으로 2가지의 Open Source가 등장하게 됨
JPA = 표준 인터페이스
하이버네이트, EclipseLink 등 = JPA 구현체
년도 | 버전 | 설명 |
---|---|---|
2003년 | 스프링 프레임워크 1.0 | XML 기반 |
2006년 | 스프링 프레임워크 2.0 | 기존 XML 기반 버전의 복잡한 설정 → XML 편의 기능 지원 |
2009년 | 스프링 프레임워크 3.0 | 자바 코드로 설정 |
2013년 | 스프링 프레임워크 4.0 | 자바8 |
2014년 | 스프링 부트 1.0 | 스프링 프레임워크의 설정 및 배포에 대한 어려움 해결하기 위해 등장 |
2017년 | 스프링 프레임워크 5.0 스프링 부트 2.0 | 리액티브 프로그래밍(비동기) 지원 |
2021년 | 스프링 프레임워크 5.3 스프링 부트 2.5 |
자바 플랫폼을 위한 자바 언어 기반의 오픈 소스 애플리케이션 프레임워크
스프링 생태계
필수
항목 | 내용 |
---|---|
핵심 기술 | 스프링 DI 컨테이너, AOP, 이벤트, 기타 |
웹 기술 | 스프링 MVC, 스프링 WebFlux |
데이터 접근 기술 | 트랜잭션, JDBC, ORM 지원, XML 지원 |
기술 통합 | 캐시, 이메일, 원격 접근, 스케줄링 |
테스트 | 스프링 기반 테스트 지원 |
언어 | 코틀린, 그루비 |
선택
항목 | 내용 |
---|---|
스프링 데이터 | DB 사용을 편리하게 해줌 ex) Spring Data Jpa |
스프링 세션 | 세션 기능 사용을 편리하게 해줌 |
스프링 시큐리티 | 보안 관련 |
스프링 Rest Docs | API 문서 관련 편리한 이용 |
스프링 배치 | 대용량 처리에 특화. 실무에서 많이 사용 |
스프링 클라우드 |
항목 | 내용 |
---|---|
경량 컨테이너 & 자바 객체 직접 관리 | - 각각의 객체 생성, 소멸과 같은 라이프 사이클을 관리한다. - 스프링으로부터 필요한 객체를 얻어올 수 있다 |
POJO 방식의 프레임워크 | 일반적인 J2EE 프레임워크에 비해 구현을 위한 특정 인터페이스 구현 및 상속 필요 x → 기존의 라이브러리 등 지원 용이 & 객체가 가벼움 |
제어 반전 (IoC : Inversion of Control) | 컨트롤의 제어권 : 사용자(x), 프레임워크(o) → 필요에 따라 스프링에서 사용자의 코드 호출 |
의존성 주입 (DI : Dependency Injection) | 각각의 계층이나 서비스들 간 의존성이 존재할 경우 → 프레임워크가 서로 연결시켜줌 |
관점 지향 프로그래밍 (AOP : Aspect-Oriented Programming) | 여러 모듈에서 공통적으로 사용하는 기능 → 해당 기능을 분리하여 관리 가능 ex) 트랜잭션, 로깅, 보안 등.. |
영속성 관련 서비스 지원 | 이미 완성도가 높은 데이터베이스 처리 라이브러리(iBATIS, 하이버네이트 등)와 연결 가능한 인터페이스 제공 |
높은 확장성 | 스프링 프레임워크에 통합하기 위해 간단하게 기존 라이브러리를 감싸는 정도로 스프링에서 사용 가능 → 수많은 라이브러리 지원 및 라이브러리 별도 분리 용이 |
항목 | 내용 |
---|---|
캡슐화 (Encapsulation) | ▪ 데이터(속성)와 데이터 처리 함수를 하나로 묶는 것 ▪ 캡슐화 된 객체의 세부 내용이 외부에 은폐(정보 은닉) → 변경 발생시 오류의 파급효과 적음 ▪ 캡슐화된 객체들 → 재사용 용이 |
정보은닉 (Information Hiding) | ▪ 다른 객체에게 자신의 정보를 숨기고 자신의 연산만을 통하여 접근을 허용하는 것 ▪ 캡슐화에서 가장 중요한 개념 |
추상화 (Abstraction) | 불필요한 부분을 생략하고 객체의 속성 중 가장 중요한 것에만 중점을 두어 개략화하는 것 (=모델화) |
상속성 (Inheritance) | ▪ 이미 정의된 상위 클래스(부모 클래스)의 모든 속성과 연산을 하위 클래스(자식 클래스)가 물려받는 것 ▪ 하위 클래스는 상위 클래스의 모든 속성과 연산을 자신의 클래스 내에서 재정의하지 않고도 즉시 자신의 속성으로 사용 가능 |
다형성 ★ (Polymorphism) | 하나의 객체가 여러 가지 타입을 가질 수 있는 것 |
다형성의 실세계 비유
실세계와 객체 지향을 1:1로 매칭하기는 어려움
역할(Interface)과 구현(Interface 구현 객체)으로 세상을 구분
예시
역할과 구현의 분리
자바 언어의 다형성 활용
객체 설계시 주의점
객체 간의 협력 관계
정리
▪ 실세계의 역할과 구현이라는 편리한 컨셉을 다형성을 통해
객체 세상으로 가져올 수 있음
▪ 유연하고 변경이 용이함
▪ 클라이언트에 영향을 주지 않고 변경이 가능
▪ 확장 가능한 설계
▪ 역할(인터페이스) 자체 변경시 클라이언트와 서버 모두 큰 변경 발생
→ 인터페이스를 안정적으로 잘 설계하는 것이 중요함
클린코드로 유명한 로버트 마틴이 좋은 객체 지향 설계의 5가지 원칙을 정리
한 클래스는 하나의 책임만 가져야 한다.
소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
public class MemberService {
private MemberRepository memberRepository = new MemoryMemberRepository();
}
public class MemberService {
/*
* 기존 코드
**/
// private MemberRepository memberRepository = new MemoryMemberRepository();
/*
* 변경 코드
**/
private MemberRepository memberRepository = new JdbcMemberRepository();
}
MemberService
클라이언트가 구현 클래스를 직접 선택"프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다."
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
프로그래머는 "추상화에 의존해야지, 구체화에 의존하면 안된다." 의존성 주입은 이 원칙을 따르는 방법 중 하나다.
MemberService
는 인터페이스와 구현 클래스를 동시에 의존MemberService
클라이언트가 구현 클래스를 직접 선택public class MemberService {
/*
* 기존 코드
**/
// private MemberRepository memberRepository = new MemoryMemberRepository();
/*
* 변경 코드
**/
private MemberRepository memberRepository = new JdbcMemberRepository();
}
스프링은 다음 기술로 다형성 + OCP, DIP를 가능하게 지원
→ 클라이언트 코드의 변경 없이 기능 확장
모든 설계에 인터페이스를 부여하는 것이 이상적
📖 참고