본문 바로가기

Development/Spring

[Spring] 스프링 부트란?

이미지 출처: https://bgasparotto.com/wp-content/uploads/2017/12/spring-boot-logo.png

Spring Framework

  • 스프링 프레임워크(Spring Framework)는 자바(java) 기반의 애플리케이션 프레임워크.
  • 현재 우리나라의 '전자정부 표준 프레임워크'의 기반 기술로 채택되어 공공기관 웹 서비스를 개발할 때도 사용.
  • 엔터프라이즈급 개발을 편리하게 만들어주는 '오픈소스 경량급 애플리케이션 프레임워크'로도 불림.
  • 스프링의 핵심 가치는 "애플리케이션 개발에 필요한 기반을 제공해서 개발자가 비즈니스 로직 구현에만 집중할 수 있게끔 하는 것"

제어 역전 (Inversion of Control)

객체의 관리를 컨테이너(Spring 컨테이너 또는 IoC 컨테이너)에 맡겨 제어권이 넘어간 것을 제어 역전이라고 부름

 

일반적인 자바 개발의 경우, 객체를 사용하기 위해 아래와 같은 코드를 사용함

package com.wikibooks.chapter1.controller;

import com.wikibooks.chapter1.service.MyService;
import com.wikibooks.chapter1.service.MyServiceImpl;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class NoDIController {

    private MyService service = new MyServiceImpl();

    @GetMapping("/no-di/hello")
    public String getHello() {
        return service.getHello();
    }

}

위 코드에서 NoDIConrtoller 클래스는 MyService 클래스를 직접 생성하고 있기 때문에, MyService를 의존하고 있음

 

  • 하지만 제어 역전(Inversion Of Control)을 특징으로 사용하는 스프링은 사용할 객체를 직접 생성하지 않고, 객체의 생명주기 관리를 '외부'에 위임함
  • 여기서 '외부'는 스프링 컨테이너(Spring Container) 또는 IoC(IoC Container)라고 함
  • 제어 역전을 통해 의존성 주입(DI; Dependency Injection), 관점 지향 프로그래밍(AOP; Aspect-Oriented Prgoramming)이 가능해짐

의존성 주입(DI)

의존성 주입이란 제어 역전의 방법 중 하나로, 사용할 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용하는 방식을 의미

스프링에서 의존성을 주입받는 방법은 세 가지가 있음

  • 생성자를 통한 의존성 주입
  • 필드 객체 선언을 통한 의존성 주입
  • setter 메서드를 통한 의존성 주입

@Autowired 어노테이션을 통해 의존성을 주입할 수 있고, 스프링 4.3 이후 버전은 생성자를 통해 의존성을 주입할 때 @Autowired 어노테이션 생략 가능

 

생성자를 통한 의존성 주입

package com.wikibooks.chapter1.controller;

import com.wikibooks.chapter1.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DIController {

    MyService myService;

    @Autowired
    public DIController(MyService myService) {
        this.myService = myService;
    }

    @GetMapping("/di/hello")
    public String getHello() {
        return myService.getHello();
    }

}

필드 객체 선언을 통한 의존성 주입

package com.wikibooks.chapter1.controller;

import com.wikibooks.chapter1.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FieldInjectionController {

    @Autowired
    private MyService myService;

}

setter 메서드를 통한 의존성 주입

package com.wikibooks.chapter1.controller;

import com.wikibooks.chapter1.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

    @RestController
    public class SetterInjectionController {

        MyService myService;

        @Autowired
        public void setMyService(MyService myService) {
            this.myService = myService;
        }

    }

 

관점 지향 프로그래밍(AOP)

  • 관점 지향 프로그래밍(AOP; Aspect-Oriented Programming)은 관점을 기준으로 묶어 개발하는 방식. 
  • *AOP는 OOP의 대체 개념이 아니며, OOP를 더욱 보완하도록 하는 개념
  • 여기서 관점이란, 어떤 기능을 구현할 때 '핵심 기능'과 '부가 기능'으로 구분하여 각각을 하나의 관점으로 보는 것을 의미
  • '핵심 기능': 비즈니스 로직을 구현하는 과정에서 비즈니스 로직이 처리하려는 목정 기능 (ex 상품 정보 등록을 요청 받아 DB에 저장)
  • '부가 기능': 비즈니스 로직 사이에 로깅(Logging) 처리나 트랜잭션 처리 

이미지 출처: https://2.bp.blogspot.com/-Rw0IF-Y-NR8/XN_Vo8ooaLI/AAAAAAAAF_4/6g3b8nEUN98Ba6UGZHW5OJNEDfn6tfFFgCLcBGAs/s1600/spring-aop-cross-cuttin-concerns.png

  • AOP의 관점에서는 부가 기능은 핵심 기능이 어떤 기능인지 무관하게 로직이 수행되기 전 또는 후에 수행되기만 하면 됨
  • 여러 비즈니스 로직에서 반복되는 부가 기능을 하나의 공통 로직으로 처리하도록 모듈화해 삽입 하는 방식을 AOP라고 함

AOP를 구현하는 방식에는 크게 세 가지가 있음 

  • 컴파일 과정에 삽입하는 방식
  • 바이트코드를 메모리에 로드하는 과정에 삽입하는 방식
  • 프록시 패턴을 이용한 방식 (스프링이 제공)

스프링 프레임워크 vs 스프링 부트

  • 스프링은 개발에 필요한 모듈들을 추가하다 보면, 설정이 복잡해지는 문제가 있었음
  • 스프링 부트는 자동 설정, 내장 서버 제공, 의존성 관리 등을 통해 개발자의 부담을 크게 줄여줌
    예를 들어, 스프링 부트는 하이버네이트를 사용한 데이터베이스 연결 설정을 자동으로 해줌
  • 또한 스프링 프레임워크에서는 개발에 필요한 각 모듈의 의존성을 직접 설정해야 했음
  • 하지만 스프링 부트는 'spring-boot-starter'라는 의존성을 제공하여, 내장 톰켓(Tomcat), 테스트(JUnit), jdbc(HikariCP), security(인증, 권한), jpa(하이버네이트를 활용한 JPA), Cache 라이브러리들을 제공함

스프링의 자동 설정

스프링 부트는 스프링 프레임워크의 기능을 사용하기 위한 자동 설정을 지원

@SpringBootApplication 어노테이션은 크게 세 개의 어노테이션을 합쳐놓은 구성임

  • @SpringBootConfiguration: 스프링 부트 애플리케이션의 설정을 정의하는 클래스를 나타냄. 이 어노테이션은 @Configuration 어노테이션을 포함하고 있어서, 스프링의 Java 기반 설정 클래스로 작동
  • @EnableAutoConfiguration: 'spring-boot-autoconfigure' 패키지 안에 spring.factories 파일을 추가해 자동 설정 적용
  • @ComponentScan: @Controller, @Service, @Repository, @Configuration 과 같은 @Component 시리즈 어노테이션을 Bean에 등록함

내장 WAS

스프링 부트의 각 웹 애플리케이션에는 내장 WAS(Web Application Server)가 존재

'spring-boot-starter-web'의 경우 톰캣을 내장

모니터링

스프링 부트는 스프링 부트 액추에이터(Spring Boot Actuator)라는 자체 모니터링 도구가 있어, 시스템이 사용하는 스레드, 메모리, 세션 등 요소들을 모니터링할 수 있음

참고 자료

스프링 부트 핵심 가이드 "스프링 부트를 활용한 애플리케이션 개발 실무" , 장정우, 2022

https://github.com/wikibook/springboot/tree/5ef2089b95ee7b6d8b70793c9cc48d6ab879d41c/chapter1/src/main/java/com/wikibooks/chapter1/controller