<< Back
blog 프로그래밍 스프링프레임워크 - 1.시작하기

이미지출처: pexels.com, Brett Sayles


스프링 프레임워크란 ?

스프링 프레임워크(Spring Framework)는 자바 기반의 오픈소스 프레임워크로 자바 EE(Enterprise Edition)에서 요구하는 수준의 복잡한 기능들을 자바 EE를 사용하지 않고 구현하고자 시작되었습니다.

2002년 Rod Johnson이 자신의 저서 “Expert One-on-One J2EE Design and Developement”에서 제시한 코드와 아이디어를 발전시켜 오늘에 이르게 되었습니다.

스프링 프레임워크 주요 특징

스프링 프레임워크에 사용된 주요 특징은 다음과 같습니다.

일반적으로 대규모 시스템은 한번 개발하면 오랜동안 유지되면 급격한 변경 보다는 점진적으로 보완하는 형태로 시스템을 유지보수해 나갑니다. 따라서 현재 구현된 많은 스프링프레임워크 기반의 시스템들은 아직까지도 3.x나 4.x 기반을 유지하는 경우가 많이 있습니다.

잘돌아가고 있는 시스템을 최신버전으로 급격하게 변경하는 경우 여러 문제가 발생할 수 있으며 새로운 버전으로 마이그레이션 하는 비용대비 이점을 잘 따져 보아야 합니다.

물론 새롭게 시스템을 구축하는 것이라면 가능한 최신버전을 검토하고 도입하는 것이 좋습니다.

스프링 프레임워크5 구조

최신의 스프링프레임워크는 v5.x 로 2017년 9월 발표되어 지금은 어느정도 안정화 되어 신규 프로젝트에 적극적으로 도입되고 있습니다.

스프링프레임워크5의 특징은 Reactive Stack 과 Servlet Stack을 구분하고 있다는 점 입니다.

이미지출처: spring.io

Servlet Stack

기존과 같이 서블릿 API 에 기반한 동기 방식의 blocking I/O 구조를 사용하며 하나의 요청은 하나의 스레드로 처리 됩니다.

Apache Tomcat 과 같은 서블릿 컨테이너를 사용하며 전통적인 Spring MVC 기반의 서버 프로그램 개발과 JPA, JDBC, NoSQL 데이터베이스 지원을 포함 합니다.

기존 스프링버전과 동일한 방식의 개발 모델과 API 구조로 이해하면 됩니다.

Reactive Stack

새로운 비동기 non-blocking I/O 구조를 사용하며 멀티코어 시스템의 장점을 살리고 대규모 사용자 접속을 처리하는데 유용한 구조로 설계 되었습니다.

Netty, Undertow 및 Servlet 3.1 이상의 컨테이너를 사용하며 Spring WebFlux라고 하는 새로운 프레임워크를 사용해 개발됩니다. 물론 Servlet 3.1 이상을 지원하는 Apache Tomcat 8.5 이상을 사용할 수도 있습니다.

리액티브(Reactive) 프로그래밍

변화에 반응하는 프로그램 모델을 말하며 기본적으로 비동기 I/O 기반으로 데이터 흐름과 변화 전파에 중점을 둔 프로그래밍 패러다임을 말합니다.

React, RxJava 등 최근 유행하고 있는 각종 프레임워크와 라이브러리들의 기본 철학으로 기존의 프로그램들이 작성된 순서에 따라 진행되는 것에 비해 리액티브 프로그래밍은 데이터의 흐름을 먼저 정의하고 데이터가 변결되었을때 연관된 함수나 수식이 업데이트 되는 방식으로 이해 할 수 있습니다. GUI 프로그램에서 이벤트 처리를 위해 사용하는 Observer Pattern 과 유사한 개념 입니다.

그렇다면 왜 최근에 리액티브 프로그래밍이 주목을 받을까요? 그 이유는 리액티브 프로그래밍 기법을 통해 개발자들이 보다 적은 작업으로 많은 일을 할 수 있으며 적은 수의 스레드로 더 많은 부하를 처리 할 수 있기 때문입니다.

언제 Reactive Stack을 사용할까요? 최신의 스프링 프레임워크의 사양이라고 해서 무조건 사용해야 하는 것은 아니고 필요에 따라 모델을 선택해 사용할 수 있습니다. 일반적으로 Reactive Stack 은 다음과 같은 구현에 적합합니다.


IoC, DI, AOP

스프링 프레임워크의 특징이며 스프링프레임워크의 구조를 이해하기 위해 반드시 알아야 하는 세가지 중요 개념 입니다.

IoC(Inversion of Control)

제어의 역행 이라고도 하며 기존의 프로그램은 main() 과 같이 프로그램이 시작되는 곳에서 필요한 객체를 생성하고 생성된 객체의 메서드를 호출하는 등의 흐름을 가지는것과 달리 IoC는 객체가 자신이 사용할 객체를 직접 생성하거나 선택하지 않는 것으로 프로그램의 제어를 자신이 아닌 다른곳에 위임하는 것을 말합니다.

스프링의 경우 스프링 컨테이너 라는 곳에서 객체를 생성하고 공급하는 역할을 담당 합니다. 스프링 빈(Spring Bean)은 스프링컨테이너에 의해 관리되는 스프링 객체를 말하는 것으로 예전에는 XML 기반의 설정 파일을 통해 객체와 관계를 정의 했으나 지금은 애너테이션을 통해 관련 설정을 하게 됩니다.

DI(Dependency Injection)

IoC 를 구현하는 방법으로 DL(Dependency Lookup)과 DI가 있습니다. DL은 저장소에 저장되어 있는 Bean에 접근하기 위해 개발자들이 컨테이너에서 제공하는 API를 이용하 Bean을 찾는 방식입니다. 당연히 컨테이너에 대한 의존성이 커지고 불필요한 코드 사용이 증가하므로 의존성 주입 으로도 불리우는 DI 방식을 사용합니다.

DI는 클래스간의 의존관계를 Bean 설정에 기반해 컨테이너가 자동으로 연결해 주는 방식입니다. 스프링프레임워크에서는 기본적으로 DI 방식을 사용 합니다.

다음의 여러 구현방법을 통해 DI개념과 스프링프레임워크를 사용한 코드를 대략적으로 이해하도록 합니다.

일반적인 구현 ShotGun 클래스는 다음에 나오는 다른 구현코드에서도 사용합니다.

class ShotGun{
  void fire() { ... }
}

class Game {
  public gameRun() {
    ShotGun sg = new ShotGun();
    sg.fire();
  }
}

팩토리패턴 구현 ShotGun 에도 속성이 다른 여러 객체가 존재할 수 있는데 객체생성을 프로그램에서 하지 않고 팩토리 클래스를 통해 필요한 인스턴스를 얻어오는 방법입니다. 디자인 패턴중 팩토리 패턴을 사용한것으로 프로그램에서는 어떤 ShotGun의 인스턴스가 전달될지 알 필요가 없습니다.

class Game {
  public gameRun() {
    ShotGun w = Factory.getInstance();
    w.fire();
  }
}

DI 구현 게임 프로그램에 필요한 ShotGun 객체가 외부에서 공급되는 형태 입니다.

class Game {
  private ShotGun sg;
  public void setShotGun(ShotGun sg) {
    this.sg = sg;
  }

  public gameRun() {
    sg.fire();
  }
}

스프링프레임워크 구현 스프링프레임워크(스프링부트사용)를 사용한 코드 입니다. 앞의 DI 적용과 유사한 구조이지만 Annotation을 사용해 객체 생성과 주입을 처리하고 있습니다.

@Component
class ShotGun{
  void fire() { ... }
}

class Game {
  @Autowired
  private ShotGun sg;

  public gameRun() {
    sg.fire();
  }
}

AOP(Aspect Oriented Programming)

관점지향 프로그래밍 이라고도 하며 스프링프레임워크 이전에 개념이 등장 했으며 스프링프레임워크의 핵심 요소중 하나입니다. 제대로 내용을 이해하고 활용하려면 꽤나 많은 학습이 필요하며 생소한 용어도 다수 등장 합니다.

지나치게 AOP 자체를 학습하는데 많은 시간을 소요하기 보다는 핵심 개념을 정리하고 스프링프레임워크등을 활용해 실제 구현에 하나씩 적용해 가면서 이해도를 높이는것이 좋습니다.

관점지향 프로그래밍이란 횡단 관심사(cross-cutting concern)의 분리를 허용함으로써 모듈성을 증가시키는 것이 목적인 프로그래밍 패러다임이라고 할 수 있습니다. 코드 그 자체를 수정하지 않는 대신 기존의 코드에 추가적인 동작인 어드바이스(Advise)을 정의 함으로써 추가된 기능이 실행되며, 어느 코드가 포인트컷(pointcut , 예를들어 특정 이름으로 시작하는 메서드등) 을 통해 수정되는지를 별도로 지정하는 구조를 가지고 있습니다.

그러면 실제 프로그램 개발시 어떤 부분에 AOP를 적용할 수 있을까? 예를 들어 뉴스와 게시판 기능을 제공하는 서비스가 있다고 할때,

대표적으로 AOP를 적용하는 분야로는 인증, 로깅, 트랜잭션 등이 있습니다.

타겟 (Target)

부가기능을 부여할 대상을 말합니다.

애스펙트 (Aspect)

AOP에서 부가기능 모듈을 애스펙트라고 부르며, 핵심기능에 부가되어 의미를 갖는 특별한 모듈이라 생각하시면 됩니다. 애스펙트는 부가될 기능을 정의한 어드바이스와 어드바이스를 어디에 적용할지를 결정하는 포인트컷을 함께 갖고 있습니다.

어드바이스 (Advice)

실질적으로 부가기능을 담은 구현부분을 말합니다. 어드바이스는 애스펙트가 ‘무엇’을 ‘언제’ 할지를 정의하고 있습니다. 어드바이스의 경우 타겟 오프젝트에 종속되지 않기 때문에 순수하게 부가기능에만 집중할 수 있습니다.

포인트컷 (PointCut)

부가기능이 적용될 대상(메소드)을 말합니다. 즉, 어드바이스를 적용할 조인포인트를 선별하는 기능을 정의한 모듈을 애기합니다.

조인포인트 (JoinPoint)

어드바이스가 적용될 수 있는 위치를 얘기합니다. 다른 AOP 프레임워크와 달리 Spring에서는 메소드 조인포인트만 제공하고 있습니다. 타 프레임워크에서는 예외 발생할 경우, 필드값이 수정될 경우 등도 지원하고 있습니다.

프록시 (Proxy)

타겟을 감싸서 타겟의 요청을 대신 받아주는 랩핑(Wrapping) 오브젝트입니다. 클라이언트가 타겟을 호출하게 되면 타겟이 아닌 타겟을 감싸고 있는 프록시가 호출되어, 타겟 메소드 실행전에 선처리, 타겟 메소드 실행 후, 후처리를 실행시키도록 구성되어있습니다.

위빙 (Weaving)

지정된 객체에 애스팩트를 적용해서 새로운 프록시 객체를 생성하는 과정을 얘기합니다. 컴파일 타임, 클래스로드 타임, 런타임과 같은 시점에서 실행되지만, Spring AOP는 런타임에서 프록시 객체가 생성 됩니다.


스프링 프레임워크 개발환경 구축

스프링 프레임워크 개발을 위해서는 통합개발도구(IDE)의 도움이 필요 합니다. 대표적인 자바 개발도구인 이클립스, 인텔리J 등은 모두 스프링 개발을 지원 합니다. 여기서는 이클립스에서 스프링 기반 개발을 위한 개발환경 구축을 살펴봅니다.

이클립스에 스프링 플러그인 설치

기존에 사용하던 이클립스가 있다면 스프링 프레임워크 개발을 위한 플러그인만 설치해도 됩니다. 가급적 이클립스는 Eclipse IDE for Enterprise Java Developer 사용을 권장 합니다.

Help -> Eclipse Market Place를 선택하고 검색창에 sts 라고 입력하면 Spring Tools 4 를 찾을 수 있습니다. Install 버튼을 눌러 설치하고 이클립스를 재시작 하면 됩니다.

플러그인 기반으로 확장 가능한 이클립스의 특징 때문에 여러 개발을 하나의 이클립스에 통합해 작업하는 것도 편리하지만 특정 개발에는 불필요한 플러그인들이 함께 동작하는 것은 여러 문제를 야기할수도 있습니다. 따라서 스프링 개발을 위해 별도로 Sprint Tools를 설치하는 것도 좋은 방법 입니다.

Spring Tools 설치

Spring Tools Suite(STS)라고 하며 스프링 프레임워크를 관리하고 있는 Pivotal 에서 배포하는 이클립스 기반의 개발도구 입니다. 이클립스에 플러그인 설치하는것과 기본적으로는 동일하지만 이클립스 버전에서 부터 각종 플러그인 버전들이 통합 패키징 되어있어 좀 더 안정적일수 있습니다.

https://spring.io/tools 에서 운영체제별로 다운로드 할 수 있습니다. 설치방법은 압축을 풀어 적절한 디렉토리에 두기만 하면 됩니다.

이 외에도 Visual Studio Code, ATOM 에디터의 플러그인들도 제공되고 있습니다.

스프링 프로젝트 생성 하기

스프링 프로젝트는 maven 이나 gradle 과 같은 빌드 도구 설정으로 부터 생성할수도 있고 스프링부트를 사용하는 경우 Spring Initializer 를 이용해 필요한 모듈로 구성된 빌드파일을 받아 프로젝트를 생성하는 방법도 있습니다. Spring Initializer는 스프링부트 프로젝트를 쉽게 생성해주는 웹 기반의 도구로 https://start.spring.io 에 접속해서 작업해도 되고 개발도구에서 제공하는 프로젝트 생성 메뉴를 사용할수도 있습니다.

STS 의 File -> New -> Spring starter project 를 실행 합니다.

다음 화면에는 프로젝트에 필요한 라이브러리들을 추가하는 화면 입니다. 키워드를 입력하면 가능한 라이브러리들이 추천 됩니다. 여기서는 AOP 실습을 위해 aop 기능을 추가 합니다. aop 로 검색되 결과를 추가 합니다.

물론 나중에 pom.xml에 직접 추가해도 됩니다.

Finish 버튼을 누르면 자동으로 프로젝트가 생성 됩니다.

스프링 부트 어플리케이션 실행

기본으로 생성된 패키지(com.example.demo)에 보면 SpringStudyApplication.java 파일이 있습니다. 스프링 부트의 메인 실행 파일로 일반적인 어플리케이션과 같이 main() 메서드를 포함하고 있습니다.

SpringStudyApplication.java

@SpringBootApplication
public class SpringStudyApplication{
	public static void main(String[] args) {
		SpringApplication.run(SpringStudyApplication.class, args);		
    System.out.println("Hello Spring Boot!!");
	}
}

파일을 선택하고 오른쪽 마우스를 클릭한 다음 Run As -> Spring Boot App 을 실행하면 다음과 같은 결과를 볼 수 있습니다.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.3.RELEASE)

2019-03-17 16:52:42.664  INFO 9872 --- [           main] com.example.demo.SpringStudyApplication  : Starting SpringStudyApplication on DinOfficeHP with PID 9872 (E:\Project\WSSpring\springStudy\target\classes started by dinfree in E:\Project\WSSpring\springStudy)
2019-03-17 16:52:42.665  INFO 9872 --- [           main] com.example.demo.SpringStudyApplication  : No active profile set, falling back to default profiles: default
2019-03-17 16:52:42.988  INFO 9872 --- [           main] com.example.demo.SpringStudyApplication  : Started SpringStudyApplication in 0.465 seconds (JVM running for 1.047)
Hello Spring Boot!!
<< Back