Spring Framework란?



spring framework는 무엇인가?


Spring Framework이란?

위키백과에 보면 스프링 프레임워크는 “자바 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크로서 엔터프라이즈급 애플리케이션을 개발하기 위한 모든 기능을 종합적으로 제공하는 경량화된 솔루션”이라고 한다. 동적인 웹 사이트를 개발하기 위한 여러 서비스를 제공하고 있다고도 나와있다. 이게 대체 무슨 말일까? 엔터프라이즈급 개발이란 기업을 대상으로 하는 개발이다. 즉 대규모 데이터 처리, 트랜잭션이 동시에 여러 사용자로부터 행해지는 큰 규모의 환경을 엔터프라이즈 환경이라 한다.

간단히 정리하면 Spring 프레임워크는 Java Enterprise Edition(기업용 자바)의 한계점을 극복하기 위한 배경에서 등장한 프레임워크다. 자바가 초기에 서버로 활용될 때에는 자바 EE를 사용했는데, 여러 문제들로 인해 로드 존슨이라는 사람이 이를 개선하기 위해 제안한 프레임 워크라고 한다. 자바로 백엔드 개발 == 자바 스프링/자바 스프링 부트라고 볼 수 있다.

Spirng Framework는 경량 컨테이너로 자바 객체를 담고 직접 관리한다. 객체의 생성, 소뮬 그리고 라이프 사이클을 관리하며 언제든 Spring 컨테이너로부터 필요한 객체를 가져와 사용할 수 있다. 이는 Spring이 IOC 기반의 프레임워크라는 것을 의미한다.

IOC?

IOC는 Inversion of Control라는 말로 제어의 역전이라는 뜻이다. 이게 무슨 말일까?

프로그래밍이란 제어를 순서화 하는 일련의 작업이다. 프로그램은 수천, 수만개의 제어로 실행되는데, 프로그래머가 이를 모두 알고 관리하기는 불가능이다. 관련성이 높은 제어와 속성을 하나로 묶어 객체를 생성하고, 객체끼리 상호작용 하도록 하는 것이 객체지향의 개념이라고 할 수 있다. 하지만 객체로 묶어도 여전히 이 객체들을 제어해야 한다. 이런 제어들의 수를 줄이는 것에 대한 고민이 “제어의 역전”이다.

여러 제어들이 있을 때 특정 작업을 하도록 만들어진 프레임워크에 이 제어의 권한을 넘겨서 클라이언트 코드가 신경 써야 할 것을 줄이는 전략이다. 이를 제어가 역전 되었다라고 하는 것이다. 여기서 잠깐 라이브러리와 프레임워크를 짚고 넘어가면, 라이브러리는 프로그래머의 코드가 라이브러리의 메소드를 호출해서 사용하고, 프레임워크의 경우에는 프레임워크의 메소드가 사용자의 코드를 호출한다.

근데 프레임워크가 어떻게 프로그래머의 코드를 호출할 수 있을까?

  1. 제어를 역전시키는(프레임워크가 내 코드를 호출할 수 있게 하는) 가장 쉬운 접근 방법은 프레임워크의 event, delegate에 코더의 메소드를 등록하는 것이다. 전달되는 인자, 반환 형식만 일치하면 프레임워크 코드는 코더가 작성한 객체와 타입을 고려하지 않는다. 등록된 메소드만 감지해서 실행하는 것이다.
  2. 프레임 워크에 정의되어 있는 interface, abstract(추상타입)을 코더의 코드에서 구현, 상속해서 프레임워크에 넘겨주는 것이다. 프레임워크는 interface와 abstract를 알고 있으므로 코더가 의도한 작업을 처리할 수 있다. 이는 객체를 프레임워크에 주입하는 것으로, 이를 의존을 주입(dependency injection)이라고 한다.

spirng framework에서의 IOC는 스프링 컨테이너가 필요에 따라 개발자 대신 Bean들을 관리해주는 행위가 된다.

spring에서는 xml 파일, 어노테이션 방식으로 스피링 컨테이너에 bean(객체)를 등록하기만 하면, 스프링 컨테이너에서 bean의 생명주기(생성->의존성 설정->초기화->소멸)를 전부 관리해준다.

DI

위에서 의존성 주입, DI를 언급했다. DI는 객체가 서로 의존하는 관계가 되게 의존성을 주입하는 것이다. 이 의존성이라는 것은 객체지향 프로그래밍에서 어떤 한 객체가 다른 객체를 사용하고 있음을 의미한다.

class Me {
  private Game game;
  
  public Me() {
    this.game = new Game();
  }
  
  public playGame() {
    this.game.play();
  }
}

위 코드를 보면 Me 라는 클래스에서 playGame()을 실행하기 위해서는 Game 클래스의 객체가 필요하다. 이를 Me 클래스는 game 클래스의 의존성을 가진다고 한다. 이렇게 코드를 설계하면 코드의 재활용성이 떨어지고, Game 클래스를 수정하면 Me 클래스도 함께 수정해야 하는 문제가 생긴다. 즉, 결합도(Coupling)가 높아진다.

DI를 이용해 코딩했을 때, 여러 장점이 있다.

  1. Unit Test가 편하다.
  2. 코드의 재활용성을 높여준다.
  3. 객체간의 의존성을 줄이거나 없앨 수 있다.
  4. 결합도를 낮춰 유연한 코드를 작성할 수 있다.

아래 코드를 보자.

class Gmae {...}

class Overwatch extends Game {}
class DestinyGuardians extends Game {}

class Me {
  private Game game;
  
  public Me() {
    this.game = new Overwatch(); //직접 수정
    this.game = new DestinyGuardians(); //직접 수정
  }
}

위와 같은 코드의 경우 직접 수정해야 하는 부분들이 많아진다.

class Me {
  private Game game;
  
  public Me(Game game) {
    this.game = game;
  }
  
  public playGame() {
    this.game.play();
  }
}

위 코드는 DI를 이용한 코드로, 의존하는 클래스를 직접 생성하지 않고 외부에서 주입 시켜줌으로써 객체간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하는 것이다.

즉, 한 클래스를 수정할 때 다른 클래스도 수정해야 하는 상황을 막는것이다.

IOC에서 DI는 각 클래스 사이에 필요로 하는 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결하는 것을 말한다.

Spring에서는 아래와 같이 DI를 적용할 수 있다.

@Component //Spring container에 bean으로 등록
public class Game {}

public class Me {
  @Autowired // 스프링 컨테이너에 있는 Game 타입의 Bean을 주입
  private Game game;
}

POJO

POJO(Plain Old Java Object)란 평범한 자바 오브젝트이다.

이전 EJB(Enterprise JavaBeans)는 확장 가능한 재사용이 가능한 로직을 개발하기 위해 사용 되었었는데 한 기능을 위해 불필요한 로직이 복잡하게 들어가는 단점이 있었다. POJO는 게터, 세터를 가진 단순 자바 오브젝트로 정의하고 있는데, 이런 오브젝트는 의존성이 없고 테스트, 유지보수가 편한 유연성의 장점을 가진다. 이로 인해 객체지향적인 다양한 설계와 구현이 가능해졌고 POJO를 지원하는 spring framework도 조명을 받게 되었다.

AOP

AOP(Aspect Oriented Programming)은 관점 지향 프로그래밍이다.

대부분의 소프트웨어 개발 프로세스에서는 OOP(Object Oriented Programming)을 사용한다. OOP는 유사한 것들을 클래스로 묶어 낮은 결합도를 갖게 한다. 하지만 이 과정 중 중복된 코드들이 많아져 가독성, 확장성, 유지보수성을 떨어뜨리게 되는데 이를 보완하기 위해 나온게 AOP이다.

AOP에서는 핵심기능과 공통기능을 분리시켜 핵심 로직에 영향을 끼치지 않게 공통기능을 끼워 넣는 개발 형태이다. 즉 어떤 로직을 기준으로 핵심 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다는 것이다.

스크린샷 2021-02-12 오전 6 59 46

위 그림을 보면 클래스마다 중복으로 사용되는 코드들이 있는데, 이를 ‘흩어진 관심사(Crosscutting Concerns)’라 한다. 이렇게 흩어진 관심사를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것이 AOP의 취지이다.

MVC

MVC란 사용자 인터페이스와 비즈니스 로직을 분리하여 개발하는 것이다. MVC는 Model1, Model2가 있는데 일반적으로 MVC는 Model2를 지칭한다.

Model

Model은 데이터 처리를 담당한다. Model은 Service와 DAO 영역으로 나뉘게 된다. 여기서 Service 부분은 불필요하게 http 통신을 하지 않아야 하고 request나 response와 같은 객체를 매개변수로 바으면 안된다. 또한 view에 종속적인 코드가 없어야 하며 view 부분이 변경되더라도 service 부분은 재사용 할 수 있어야 한다.

Model은 View와 Controller에 대해 전혀 모른다.

View

View는 사용자 interface를 담당하며 사용자에게 보여지는 부분이다. View는 Controller를 통해 데이터에 대한 시각화를 담당하며 View는 자신이 요청을 보낼 Controller의 정보만 알고 있어야 한다.

Model이 가진 정보를 저장하면 안되고 Model, Controller의 구성 요소를 알아서는 안된다.

Controller

View에서 받은 요청을 가공해 Model에 전달하고, Model에게 받은 결과를 View로 전달한다. Controller에서는 모든 요청 에러와 모델 에러를 처리한다.

Model과 View의 정보에 대해 알고 있어야 한다.

M, V, C를 나누는 이유는 소스를 분리해서 각 소스의 목적을 명확하게 하고 유지보수하기 편하게 하기 위해서이다. Model의 Service 여역은 자신을 어떤 Controller가 호출하든 상관없이 정해진 매개변수만 받는다면 자신의 비즈니스 로직을 처리할 수 있어야 한다.

Spring Framework의 구조

스크린샷 2021-02-12 오후 1 46 08

Spring Core

Spring Core는 Spring Container를 의미한다. Container는 Fpring Framework의 핵심이며 그 중 핵심은 Bean Factory Container이다. Bean Factory는 IOC 패턴을 적용하여 객체 구성부터 의존성 처리까지 모든 일을 처리하고 있다.

Spring Context

Spring context는 Spring Framework의 context 정보들을 제공하는 설정 파일이다. Spring Context에는 JNDI, EJB, Validation, Scheduling, Internalization등 엔터프라이즈 서비스를 포함하고 있다.

Spring DAO

DAO는 Data Acess Object의 약자로 Database Data에 접근하는 객체이다. Spring JDBC DAO는 추상 레이어를 지원함으로써 코딩이나 예외처리 하는 부분을 간편화 시켜 일관된 방법으로 코드를 짤 수 있게 도와준다.

Spring ORM

ORM은 Object relational mapping의 약자로 객체와의 관계 설정을 하는 것이다. Spring에서는 Ibatis, Hibernate, JDO등 인기 있는 객체 관계형 도구를 사용할 수 있게 지원한다.

Spring Web

Spring에서 web context module은 Application module에 내장되어 있고 Web 기반의 응용프로그램에 대한 Context를 제공해 일반적인 web application 개발에 필요한 기본적인 기능을 지원한다.

그렇다면 Spring을 사용하는 이유는 무엇일까?

1. 정적 타입 언어로서의 강점

동적 타이핑과 맞아떨어지는 내용은 아니지만, 나로서는 요즘 굉장히 체감이 되는 것이 자바스크립트는 디버깅 하기가 굉장히 힘들다. 오타를 내도 오류를 내지 않고 일단 실행시켜주는 동적 타입 언어라는 특징이 이런 복잡성을 느끼게 해준다.

예를 들어 아래와 같은 코드가 있다고 해보자.

const arr1 = [1, 2, 3, 4];
const arr2 = ['1', '2', '3', '4'];

const reduceArr = arr => arr.reduce((left, right) => left + right);

reduceArr(arr1); // 10
reduceArr(arr2); // '1234'

코더가 의도한 바는 배열 안에 있는 모든 원소를 더해 첫 번째 결과와 같이 출력하는 것이겠지만, 두 번째 결과를 보면 알 수 있다시피 javascript에서는 이런 의도를 미리 감지하고 오류를 출력하는 등의 방법으로 막지 않는다.

반면에 자바는 정적 타이핑을 사용하므로 javascript보다는 코더의 의도를 캐치하고 사전에 오류를 낼 수 있다.

public int reduceArr(int[] arr) {
    int result = 0;
    for (int e : arr) {
        result += e;
    }
    return result;
}

final int[] arr1 = new int[4] { 1, 2, 3, 4 };
final String[] arr2 = new String[4] { "1", "2", "3", "4" };

System.out.println(reduceArr(arr1)); // 10
System.out.println(reduceArr(arr2)); // 말도 안되는 호출이므로 바로 빨간줄 그어짐

위처럼 함수를 작성할 때 입 출력의 타입을 지정함으로써 사전에 잘못된 호출을 막을 수 있다. 이런 장점은 협업할 때, 긴 시간 작업할 때 도움이 된다. 다른 사람이 작성한 코드를 짧은 시간만에 이해해서 올바르게 사용하거나, 아주 오래 전에 작성한 코드의 쓰임새를 정확하기 기억하고 사용하기는 힘들다. 이 때문에 큰 서비스 개발에는 정적 타입 언어가 선호된다고 한다.

하지만 이는 spring을 사용하는 데 큰 이유는 되지 못한다. 동적 타이핑의 단점을 커버하는 TypeScript가 있기 때문이다. 이 TypeScript에 대한 내용은 기회가 되면 다음에 공부해서 올려보도록 하겠다.

2. 컴파일된 언어로서의 장점

자바, js, python의 공통점은 가상 머신(Virtual Machine)을 기반으로 작동한다는 것이다. 그 중에서도 자바만의 특징은 자바는 컴파일 된다라는 점이다. 이 컴파일이라는 것은 인간의 언어를 컴퓨터가 알아들을 수 있는 기계어로 바꾸는 개념, 즉 “미리 번역해서 기계어로 만들어버린다” 라는 개념이고 인터프리터는 “한 줄 읽을때마다 기계어로 번역해서 주자”라는 개념이다.

이 때문에 컴파일러가 인터프리터보다 압도적으로 빠르다. 게다가 컴파일 과정에서 소스 코드를 미리 훑어봄으로써 여러 에러를 감지하고 최적화를 수행할 수도 있다. 자바는 기계어가 아닌 JVM(자바 가상머신)이 이해하는 ‘바이트 코드’로 변환되기 때문에 C, C++ 처럼 좋은 성능은 나오지 않는 것이다. 하지만 인터프리터 언어보다는 빠르다.

하지만 자바가 주류인 이유는 역시 이 때문만은 아니다. 파이썬과 같은 언어들도 JIT 컴파일을 지원해서 실행 전에 컴파일이 되게 할 수 있다.

3. Spirng이 제공하는 도구들

1, 2와 같은 경우는 spring이 아닌 java에 좀 더 가까운 내요이다. 스프링은 자바 EE를 개선하기 위해 나온 프레임 워크인데, 그 때문에 기업이 애플리케이션을 만들 때 필요한 도구는 거의 다 갖추고 있다 라고 할 수 있다.

Spring Security

  • 인증에 관한 라이브러리, 로그인과 회원 가입, 적정 유저의 접근 권한 등을 관리하며, 소셜로그인이라 불리는 OAuth도 지원한다.

node.js의 경우 passport라 불리는 third party를 받아서 사용해야 한다.

Spring Jdbc

  • DB 접속에 관한 라이브러리. DB 커넥터를 바꿔가면서 사용할 수 있다. 즉 mysql을 쓰다가 oracle db로 변경할 일이 있어도, 인터페이스는 변하지 않아 코드 상으로 변경할 점이 많지 않다.

node.js의 경우 mysql을 사용하고 싶다면 mysql2라는 third party 패키지를 사용해야 한다. db를 바꾸고 싶다면 다른 패키지를 받아 사용해야 한다.

Spring Actuator

  • 해당 웹 서버의 Health Check, 모니터링 등을 도와주는 라이브러리이다.

위에 언급된 것들 외에도 다양한 라이브러리를 지원하며, netflix와 같이 기업에서 자체적으로 라이브러리에 기여하기도 한다. Spring은 대규모 서비스에서 사용되고 있다고 했는데, 이미 검증된 라이브러리를 사용하는 것이 기업 입장에서는 합리적인 선택이다. 하지만 이런 이유라면 큰 서비스를 제공하는 회사들에서 spring을 사용하는 것이 맞아 보이는데, 그렇지 않은 회사들도 있다.

4. 개발자 구인의 용이성

자바는 굉장히 많은 곳에서 사용되고 있다. 특히 ‘전자정부프레임워크’ 라는 자바 스프링 기반으로 만들어진 프레임워크 때문에 공공기관과 관련된 일을 하는 회사들이 자바를 이용할 수 밖에 없었다. 이 때문에 자바 개발자의 수가 많아졌고, 그 결과 많은 경력자들이 사용하는 java spring이 더 힘을 얻게 되는 계기가 되었다.

출처

spring이 대체 뭔지, 그리고 왜 사용하는지 정말 친절하고 자세히 설명한 블로그 글 [https://seolin.tistory.com/119] [https://khj93.tistory.com/entry/Spring-Spring-Framework%EB%9E%80-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%ED%95%B5%EC%8B%AC-%EC%A0%95%EB%A6%AC] IOC [https://vandbt.tistory.com/43] AOP [https://engkimbs.tistory.com/746] DI [https://velog.io/@wlsdud2194/what-is-di] [https://velog.io/@damiano1027/Spring-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85-%EC%A0%9C%EC%96%B4%EC%9D%98-%EC%97%AD%EC%A0%84]