스프링 프레임워크의 정의와 주요 특징

.·2021년 9월 7일
0
post-thumbnail

이진숲 스터디 발표 자료
1. 스프링 프레임워크란?
2. 스프링 프레임워크의 주요 특징

Spring Framework란?

자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크

스프링 프레임워크을 줄여서 스프링이라고도 많이 부른다.
위 정의는 무슨 뜻일까?? 네 부분으로 나누어서 하나씩 살펴보자.

1. "자바 엔터프라이즈 개발을 편하게 해주는"

  • 엔터프라이즈급 개발: 기업을 대상으로 하는 개발
  • 엔터프라이즈급 환경: 데규모 데이터 처리와 트랜잭션이 동시에 여러 사용자로부터 행해지는 매우 큰 규모의 환경

EJB(Enterprise Java Beans)

스프링이 있기 이전에 자바로 엔터프라이즈 애플리케이션을 개발하는 가장 일반적인 방법은 EJB를 사용하는 것이었다.

  • EJB 1.0 명세의 overall goal
    • low level의 API 등을 이해하지 못하더라도 아무런 문제없이 애플리케이션을 개발할 수 있다.

위와 같은 목표를 가지고 처음 등장을 했지만, 기대와 달리 무겁고, 복잡, 불편한 점이 많았다.
스프링은 이 잘못 돌아가는 상황에 대한 대안을 찾다가 등장

Spring Framework

  • 스프링 프레임워크를 사용하는 이유
    1. 기존 자바 기반의 다른 프레임워크들(EJB, JavaEE)보다 테스트하기 쉽고
    2. 사용하기 간단하며
    3. 유연한 아키텍쳐를 가졌고
    4. 트렌드를 잘 반영하기 때문

스프링 프레임워크가 제공하는 기술이 아니라 자신이 작성하는 애플리케이션의 로직에 더 많은 관심과 시간을 쏟게 해준다.
초기에 스프링의 기본 설정과 적용 기술만 잘 선택하고 준비해두면, 이후로 애플리케이션 개발 중에는 스프링과 관련된 코드나 API에 대해 개발자가 거의 신경쓸 일이 없다.

2. "오픈소스"

  • 오픈소스 프로젝트 방식으로 개발된 스프링

오픈소스: 소스가 모두에게 공개되고, 특별한 라이선스를 취득할 필요없이 얼마든지 가져다 자유롭게 이용해도 된다.

Spring의 저장소: https://github.com/spring-projects/spring-framework
Spring: Apache License 2.0을 따른다.
Apache Server : 'open source' 라이선스에 따라 배포되어 마음대로 쓸 수 있는 Http 웹 서버

3. "경량급"

  • 단순한 개발툴과 기본적인 개발환경으로도 엔터프라이즈 개발에서 필요로 하는 주요한 기능을 갖춘 애플리케이션을 개발하기에 충분하다

작은 규모의 코드로 이루어졌다라는 뜻이 아님

EJB vs Spring Framework

  • EJB는 고가의 제품으로 구성된 제대로 된 개발환경을 갖추지 않고는 개발하기가 힘들었지만
  • 스프링 프레임워크를 사용하면 단순한 개발툴기본적인 개발환경으로도 엔터프라이즈 개발에서 필요로 하는 주요한 기능을 갖춘 애플리케이션을 개발하기에 충분하다는 뜻에서의 '경량'이다

웹 컨테이너나 가볍고 단순한 환경에서도, 복잡한 EJB와 고가의 WAS를 갖춰야만 가능했던 엔터프라이즈 개발의 고급 기술을 대부분 사용할 수 있다.
따라서 만들어진 코드가 지원하는 기술수준은 비슷하더라도 훨씬 빠르고 간편하게 작성하게 해줌으로써 생산성과 품질 면에서 유리하다.

4. "애플리케이션 프레임워크"

  • 특정 계층이나, 기술, 업무 분야에 국한되지 않고 애플리케이션의 전 영역을 포괄하는 범용적인 프레임워크
  • 애플리케이션 개발의 전 과정을 빠르고 편리하며 효율적으로 진행하는데 일차적인 목표를 둔다

프레임워크: 소프트웨어의 구체적인 부분에 해당하는 설계와 구현을 재사용이 가능하게끔 일련의 협업화된 형태로 클래스들을 제공하는 것(Ralph Johnson) = 기본적으로 구성하는 뼈대

  • 일반적으로 라이브러리나 프레임워크는 특정 업무 분야나 한 가지 기술에 특화된 목표를 가지고 만들어지지만
  • 애플리케이션 프레임워크는 특정 계층이나 기술, 업무 분야에 국한되지 않고 애플리케이션의 전 영역을 포괄하는 범용적인 프레임워크를 말한다.

주요 특징

  1. 경량 컨테이너로서 자바 객체를 직접 관리한다.
  2. Plain Old Java Object(POJO) 기반의 프레임워크이다.
  3. 제어 반전(IoC : Inversion of Control)을 지원한다.
  4. 의존성 주입(DI : Dependency Injection)을 지원한다.
  5. 관점 지향 프로그래밍(AOP : Aspect-Oriented Programming)을 지원한다.
  6. 영속성과 관련된 다양한 서비스를 지원한다.
  7. 확장성이 높다.

1. 경량 컨테이너로서 자바 객체를 직접 관리한다.

Spring Container

스프링 프레임워크는 개발자를 대신해서 스프링의 빈을 생성하고 관리하는 컨테이너를 가지고 있고, 이를 스프링 컨테이너라고 부른다. 컨테이너가 대신 빈을 관리(Inversion of Control, 제어의 역전)해주기 때문에 개발자는 모듈 간의 의존과 결합으로 인해 발생하는 문제로부터 자유로워졌다.

  • 각각의 객체 생성, 소멸과 같은 라이프 사이클을 관리하며 스프링으로부터 필요한 객체를 얻어올 수 있다.
  • IoC 컨테이너, Bean Factory라고도 부름
    • 제어권이 개발자에게서 스프링으로 넘어갔기 때문

스프링이 처음 뜰 때 스프링 컨테이너라는 통이 생기는데 컨테이너에 ComponentScan을 통해 @Component가 붙은 클래스들의 객체인 스프링 빈을 생성하여 컨테이너에 넣어두고 관리한다.

  • BeanFacory: 스프링 컨테이너의 최상위 인터페이스, 스프링 빈을 관리, 조회하는 역할
  • ApplicationContex: BeanFactory의 모든 기능을 상속받고, 편리한 부가 기능들도 함께 제공

Spring Bean

  • Spring IoC 컨테이너가 관리하는 자바 객체
    • new 키워드로 생성한 객체는 빈이 아니다
  • ApplicationContext.getBean()으로 가져올 수 있다.
    • ApplicationContext이 만들어서 그 안에 담고 있는 객체
  • Singleton Scope
    • 어플리케이션 전반에 걸쳐 빈의 인스턴스를 오직 하나만 생성해서 사용

애플리케이션을 작성할 때 의존성 주입을 받아 의존 객체로 사용하고 싶은 경우에는 객체를 bean으로 만들어주어야 한다.

Spring Bean 등록 방법

  1. Component Scan과 자동 의존관계 설정

    • Application을 포함한 하위 패키지의 모든 Component를 스캔
    • @Component가 있으면 스프링 빈으로 자동 등록
    • @Controller, @Service, @Repository는 모두 @Component를 포함
    • 의존성 주입(Dependency Injection)을 받아 의존 객체로 사용하고 싶을 경우 스프링 빈으로 만들어주어야 한다.
      ex> MemberService가 MemberRepository의 의존성을 주입받고자 함. 하지만 MemberRepository가 스프링 빈으로 등록되지 않았을 시 autowired로 의존할 수 없다.
  2. Configuration에서 @Bean을 통해 직접 스프링 빈 등록하기

2. Plain Old Java Object(POJO) 기반의 프레임워크이다.

  • POJO: 평범한 구식 자바 객체/오래된 방식의 간단한 자바 오브젝트

조건

  1. 특정 규약(contract)에 종속되지 않는다.
    • Java 언어와 꼭 필요한 API 외에 종속되지 않는다.
  2. 특정 환경에 종속되지 않는다.
  3. 객체지향 원리에 충실해야 한다.
    • 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트

왜 이름이 POJO일까??

또다시 EJB 두둥등장
마틴 파울러는 널리 사용된 복잡하고 무거운 EJB(Enterprise Java Beans)보다는 단순한 자바 객체에 도메인 로직을 넣어서 사용하는 것이 훨씬 편리하고 많은 장점이 있는데 왜 사람들이 EJB가 아닌 평범한 자바 오브젝트를 사용하기를 꺼려하는지에 의문을 가졌다.
이 의문에 대한 답으로 단순한 오브젝트는 EJB와 같은 그럴듯한 이름이 없어서 사람들이 그 사용을 주저하는 것이라고 결론을 내렸고, plain old java object(POJO)라는 용어를 만들었다.

사용 이유

  1. 코드의 간결함
    • 특정 환경이나 low level 종속적인 코드와 비즈니스 로직을 분리
  2. 자동화 테스트에 유리
    • 환경 종속적인 코드가 아니다
  3. 객체지향 설계의 자유로운 사용

예시

Bean class

Spring을 이용하면 POJO 프로그램의 장점을 살려서 깔끔하고 간결하게 코드를 작성 가능하다.

spring.io/understanding/POJO

스프링 삼각형(Spring Triangle)

  • Spring Source의 CTO가 스프링의 핵심 개념들을 설명하기 위해 만든 그림
  • 스프링으로 개발한 애플리케이션의 기본 구조

3, 4. 제어 반전(IoC : Inversion of Control)과 의존성 주입(DI : Dependency Injection)을 지원한다.

IoC

  • 컨트롤의 제어권이 사용자가 아니라 프레임워크에게 있어서 필요에 따라 스프링에서 사용자의 코드를 호출한다.

컨테이너가 개발자를 대신하여 메서드가 호출될 때와 메서드가 필요한 자원을 전달하는 설계 구조
제어의 흐름을 바꿈으로써 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 해서 가독성이나 코드 중복, 유지 보수를 편하게 할 수 있게 한다.

DI

  • 각각의 계층이나 서비스들 간에 의존성이 존재할 경우 프레임워크가 서로 연결시켜준다.

스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능이다.
객체를 직접 생성해서 객체 의존관계를 주는 것이 아닌, 외부에서(스프링이) 생성해서 주입시켜주는 방식
IOC는 메서드가 필요로 하는 자원을 코드가 실행될 때 전달한다.
모듈 간의 결합도가 낮아지고 유연성이 높아진다.

  • 예시
    (위) 객체를 생성하고, 클래스 내부에서 의존하는 객체를 new 키워드를 통해 개발자가 직접 생성, 의존성 객체의 메소드 호출
    (아래) 클래스 내부에서 객체를 만드는 것이 아닌, 제어권을 스프링에게 위임하여 스프링에서 객체를 생성하고, autowired를 통해 스프링이 만들어놓은 객체를 주입받는다.

Singleton

  • 각 Service에서 new를 통해 각자 직접 객체를 생성했기 때문에 두 memberRepository는 다른 인스턴스
  • MemberRepository를 스프링 빈으로 등록하면 기본으로 싱글톤으로 등록되기 때문에, 각 Service에서 레포지토리를 주입받는다면 같은 인스턴스를 사용한다.

DI 주입 방법

  1. 필드 주입
    • field를 생성만 해두고 바로 autowired로 주입받는 방식
    • 문제점: Field injection is not recommended 경고 문구
  1. Setter 주입
    • 생성을 미리 해두고 나중에 set으로 의존성을 주입받는 방식
    • 문제점: 다른 곳에서 MemberService를 호출했을 때 setter가 public으로 노출되고, 애플리케이션 동작 중간에 의존성이 또다시 set이 될 수도 있다.
  1. 생성자 주입(권장)
    • 처음 애플리케이션이 실행되는 시점에 의존성이 한 번만 주입되고 끝난다.
    • 생성자가 1개만 있으면 @Autowired는 생략 가능

5. 관점 지향 프로그래밍(AOP : Aspect-Oriented Programming)을 지원한다.

  • 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다
  • 트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통적으로 사용하는 기능의 경우 해당 기능을 분리하여 관리할 수 있다.
    • Logging, Security, Transaction 등을 aspect라는 특별한 객체로 모듈화
    • 이 모듈을 핵심 기능에 끼워넣는다.

핵심 비즈니스 로직과 관련이 없고, 여러 곳에서 공통적으로 쓰이는 기능들을 공통 관심사로 분리하여 개발하고, 실행 시에 서로 조합할 수 있다.
애플리케이션 로직을 담당하는 코드에 남아있는 기술 관련 코드를 분리해서 별도의 모듈로 관리하게 해주는 강력한 기술
코드를 단순하고 깔끔하게 작성할 수 있다.

  • 예시
    • AOP 적용 전
      동일한 일을 하는 코드인 AAAA, BBBB가 여기저기서 사용된다
      코드 변경이 필요할 때마다 일일이 다 찾아서 바꾸어주어야 함
    • AOP 적용 후
      중복되는 코드를 떼어내서 분리
      ex> 각 메소드의 실행 시간을 로그로 찍는 작업을 aop로 구현
      실행 시간을 계산하기 위해서는 모든 메소드의 시작과 끝에 시간과 로깅 관련 코드를 넣어주어야 한다. -> AAAA, BBBB
      @LogExecutionTime이라는 annotation을 만들어서 적용

      메소드 a(), b(), c()는 자신이 해야할 작업인 핵심 로직 aaaa, bbbb, cccc만을 가지게 된다.

6, 7. 이식 가능한 서비스 추상화(PSA: Portable Service Abstraction)를 지원한다.

  • 서비스 추상화: 추상화 계층을 사용하여 어떤 기술을 내부에 숨기고 개발자에게 편의성을 제공해준다.

  • 예시
    @Transactional을 선언하는 것만으로도 내부적으로 트랜잭션 코드가 추상화되어서 숨겨져 있기 때문에 별도의 코드 추가 없이 트랜잭션 서비스를 이용 가능하다.

스프링은 완성도가 높은 라이브러리와 연결할 수 있는 인터페이스를 제공하고, 다른 프레임워크들과의 통합을 지원한다.

6. 영속성과 관련된 다양한 서비스를 지원한다.

  • iBATIS나 하이버네이트 등 이미 완성도가 높은 데이터베이스 처리 라이브러리와 연결할 수 있는 인터페이스를 제공한다.

7. 확장성이 높다.

  • 스프링 프레임워크에 통합하기 위해 간단하게 기존 라이브러리를 감싸는 정도로 스프링에서 사용이 가능하기 때문에 수많은 라이브러리가 이미 스프링에서 지원되고 있고 스프링에서 사용되는 라이브러리를 별도로 분리하기도 용이하다.

더 알아보고 싶은 부분

  • Spring MVC 패턴
  • Spring Framework 구조
  • Spring Container 구조
  • Servlet이란?
  • Spring vs SprintBoot
    등등..
  • Spring 기능요소

0개의 댓글