[ Spring ] 스프링이란?




스프링은 어떤 하나의 기술이 아니라 여러가지 기술의 집합체라고 볼 수 있다.

이중 스프링의 가장 핵심이 되는 스프링 프레임워크, 여러 스프링 기술들을 편리하게 사용할 수 있도록 해주는 스프링 부트,

그리고 선택적으로 사용할 수 있는 스프링 데이터, 스프링 세션, 스프링 시큐리티, 스프링 Rest Docs, 스프링 배치, 스프인 클라우드 등이 있다.

TMI. 왜 스프링일까? 👀

스프링이 로드 존슨에 의해 세상에 나오기전, 자바 개발자들은 EJB를 사용했다. 문제는 굉장히 비쌌고, 느리고 무거웠음.

로드 존슨이 2002년에 EJB의 문제점을 지적하면서 EJB없이도 충분히 고품질의 어플리케이션을 개발할 수 있음을 보여주면서 예제코드로 3만 라인 이상의 기술을 보여줬다.

이로써 자바진영의 겨울이 끝나고 봄이 왔다고 하여 (진짜임) 스프링이라고 이름 붙였다고 한다 (ㅋㅋ재밌네)





스프링 프레임워크
  • 핵심기술 : 스프링 DI컨테이너, AOP, 이벤트, 기타
  • 웹 기술 : 스프링 MVC, 스프링 WebFlux
  • 데이터 접근 기술 : 트랜잭션, JDBC, ORM지원, XML 지원
  • 기술 통합 : 캐시, 이메일, 원격접근, 스케줄링
  • 테스트 : 스프링 기반 테스트 지원
  • 언어 : 코틀린, 그루비
  • 최근에는 스프링 부트를 통해서 스프링 프레임워크의 기술들을 편리하게 사용



스프링 부트
  • 스프링을 편리하게 사용할 수 있도록 지원, 최근에는 기본으로 사용
  • 단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성
  • Tomcat 같은 웹 서버를 내장해서 별도의 웹 서버를 설치하지 않아도 됨
  • 손쉬운 빌드 구성을 위한 starter 종속성 제공
  • 스프링과 3rd party(외부) 라이브러리 자동 구성
  • 메트릭, 상태확인, 외부 구성 같은 프로덕션 준비 기능 제공
  • 관례에 의한 간결한 설정




그럼 로드 존슨은 스프링을 왜 만들었을까? 만들면서 어떤 핵심 컨셉을 가지고 스프링을 만들었을까?


⭐️ 스프링의 핵심 컨셉은 객체 지향 언어가 가진 강력한 특징을 살려내기 위한 프레임워크이다. ⭐️

스프링은 자바 기반의 프레임워크인데, 자바의 가장 큰 특징은 객체 지향 언어라는 것이다.

고로, 스프링은 좋은 객체 지향 어플리케이션을 개발할 수 있게 도와준다. 이게 스프링의 가장 큰 핵심이다.




객체 지향 프로그래밍이란?

사실 너무 기본인 내용이지만, 1. 추상화, 2. 캡슐화, 3. 상속, 4. 다형성 등등등이 객체 지향의 특징이다.

프로그램을 ‘객체들의 모임‘으로 파악하는 것, 프로그램을 유연하고 대체가 용이하게 만들 수 있다는게 특징인데

유연하고 변경이 용이하다는 것은 다형성(Polymorphsim)이라고 한다(어찌보면 객체 지향의 특징중 가장 중요한 특징)

(Ex. 어떤 차를 운전하든 운전을 할 수 있는 사람이라면 운전이 가능하다. 공연을 한다면 배우가 누구이든 공연을 진행할 수 있다)

위의 예시처럼 역할과 구현을 구분하면 유연성과 변경 편리성이 올라간다.

  • 클라이언트는 대상의 역할(인터페이스)만 알면 된다.
  • 클라이언트는 구현 대상의 내부 구조를 몰라도 된다.
  • 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다.
  • 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않는다




스프링과 객체 지향

스프링은 다형성을 극대화해서 객체 지향의 특징을 잘 살릴 수 있도록 도와준다.

특히 IoC, DI은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원한다.

그런데, 좋은 객체 지향 프로그램을 만들기 위해서는 다형성 말고 하나의 개념을 더 알아야하는데, 그게 바로 SOLID라는 5가지 원칙이다.




좋은 객체 지향 설계의 5가지 원칙 (SOLID)
  • SRP(Single Responsibility Principle) : 단일 책임 원칙
    • 하나의 클래스는 하나의 책임만 가져야 한다
    • 그렇지만 하나의 책임이라는 것은 모호하므로, 변경을 기준으로 한다. 변경이 있을때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것이다. 모델1 구조로 만들어진 몇만라인 JSP코드를 수정해야 할 때, 개발한 개발자만 수정할 수 있다면 단일 책임 원칙을 따르지 못한것이다.


  • OCP(Open/Closed Principle) : 개방-폐쇄 원칙
    • 가장 중요한 원칙
    • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
    • 확장을 하려면 당연히 기존 코드를 변경해야한다고 생각할 수 있으나, 다형성의 개념으로 생각해보면, 새로운 클래스를 만들어서 새로운 기능을 구현하는것(확장)이 기존 코드에는 아무런 영향을 주지 않기 때문이다.
    • 그런데, 실제로 구현 객체를 변경하려면 클라이언트 코드를 변경할 수 밖에는 없다.
    • 분명 다형성을 사용했지만 OCP원칙을 지킬 수 없다.
    • 객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정자가 필요한데, 이걸 스프링이 해준다.


  • LSP(Liskov Substitution Principle) : 리스코프 치환 원칙
    • 프로그램 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다
    • 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것, 다형성을 지원하기 위한 원칙, 인터페이스를 구현한 구현체는 믿고 사용하려면 이 원칙이 필요하다
    • 단순히 컴파일에 성공하는 것을 넘어서는 이야기
    • 예를 들어 자동차 인터페이스의 엑셀은 앞으로 가라는 기능이므로 내가 개인적으로 뒤로 가게 구현한다면 컴파일에는 성공하겠지만 LSP를 위반한게 된다. 느리더라도 ‘앞으로’ 나가야 함


  • ISP(Interface Segregation Principle) : 인터페이스 분리 원칙
    • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
    • 예를 들어 자동차 인터페이스를 운전 인터페이스와 정비 인터페이스로 분리시키고, 사용자 클라이언트도 운전자 클라이언트와 정비사 클라이언트로 분리시킨다면 정비 인터페이스가 변해도 운전자 클라이언트에 영향을 주지 않는다.
    • 이렇게 분리를 하면 인터페이스가 명확해지고, 대체 가능성이 높아진다


  • DIP(Dependency Inversion Principle) : 의존관계 역전 원칙
    • 가장 중요한 원칙
    • 구현 클래스에 의존하지 말고, 인터페이스에 의존해야한다. => 역할에 의존해야함
    • 예를 들어 A배우가 B배우 랑만 호흡을 맞췄다고 B랑만 공연할 수 있다고 말할수 있는가? 아님. A가 자신의 대본을 다 외웠다면 C,D,E 등등등 그 어떤 배우가 와도 구현해낼 수 있음. 그렇기 때문에 자신의 역할에 집중해야 유연하게 구현체를 변경할 수 있다는 말.
    • 구현체에 의존하게 되면 변경이 아주 어려워진다. ‘저 B배우랑만 연습했으니까 C배우랑은 공연 못해요’ 라는 말이랑 똑같음. 그리고 이 말은 ‘추상화에 의존해야지 구체화에 의존하면 안된다’ 라는 문장과 같은 말이다



지금까지 객체 지향의 가장 큰 특징인 다형성과 SOLID에 대해 알아봤는데,

다형성만으로는 OCP, DIP를 지킬 수 없다 ( 다형성만으로는 클라이언트 코드의 변경을 막을 수 없다. 그렇다고 OCP, DIP을 끝까지 지키자니 구현체가 없고 인터페이스만 존재한다면 서비스가 구현되지 않으므로 작동하지 않는다는 문제가 발생한다 )

이때 스프링을 이용할 수 있는데, 스프링은 다형성과 OCP, DIP를 같이 가능하게 지원해준다

바로 DI와 DI 컨테이너를 통해서 가능하게 만들어준다.




좋은 객체 지향프로그램을 예로 들어 정리하자면,

공연을 설계하듯이 배역만 만들어두고, 배우는 언제든지 유연하게 변경할 수 있도록 만드는 것이 좋은 객체 지향 설계이다!














김영한님의 스프링 핵심 원리 - 기본편 수업들으면서 정리!




© 2018. by sora

Powered by sora