스프링 부트 핵심 가이드 책을 보고 정리한 내용입니다.
스프링 프레임워크(Spring Framework)는 자바 기반의 애플리케이션 프레임워크이다. 엔터프라이즈급 애플리케이션을 개발하기 위한 다양한 기능을 제공하며 목적에 따라 다양한 프로젝트를 지원하는데 그중 하나가 스프링 부트(Spring Boot)이다.
스프링부트의 기반이 되는 스프링 프레임워크를 알아보고, 그것을 기반으로 스프링부트 특징을 정리해 보자.
스프링 프레임워크?
스프링 프레임워크는 자바에서 가장 많이 사용되는 프레임워크이며, 우리나라에서는 '전자정부 표준 프레임워크'로 채택되어 웹 개발자들에겐 익숙한다.
스프링 프레임워크는 자바를 이용해 엔터프라이즈급 개발을 편하게 만들어주는 '오픈소스 경량급 애플리케이션 프레임워크'로 불린다. 즉, 자바로 애플리케이션을 개발하는데 필요한 기능을 제공하고 쉽게 사용하도록 돕는 도구이다.
엔터프라이즈급 개발?
기업 환경을 대상으로 하는 개발을 뜻합니다. 대규모 데이터 처리와 트랜잭션이 동시에 여러 사용자로 부터 행해지는 매우 큰 규모의 환경을 엔터프라이즈 환경이라 부른다.
스프링은 해당 환경에 맞게 설계되어 있어 개발자는 "애플리케이션 개발에 필요한 기반을 제공되기 때문에 비즈니스 로직 구현에만 집중" 할 수 있다. 이것이 스프링을 사용하는 핵심가치이다.
스프링 프레임워크의 특징
1. 제어 역전(IoC)
일반적인 자바 개발의 경우 객체를 사용하기 위해선 new를 이용해 객체를 선언하고 해당 객체의 의존성을 생성한 후 객체에서 제공하는 기능을 사욯한다.
즉, 객체를 생성하고 사용하는 일련의 과정을 개발자가 직접 제어하야 한다.
@RestContoller
public class ExContoller {
// new를 이용한 객체선언하여 의존성 생성
private MyService service = new MyServiceImpl();
@GetMapping("/hello")
public String getHello(){
// 객체가 제공하는 기능사용
return service.getHello();
}
}
하지만 제어 역전(IoC : Inversion of Control)을 특징으로 하는 스프링은 기본 자바 개발 방식과 다르게 동작한다. IoC 환경에서는 객체를 직접 생성하지 않고 객체의 생명주기를 외부에 위임한다.
여기서 외부는 스프링 컨테이너 또는 IoC 컨테이너를 의미한다. 객체의 관리를 컨테이너에 맡겨 제어권을 넘기는 것이 제어 역전이라고 한다. 스프링에서는 역전제어를 통해 의존성 주입(DI), 관점 지향 프로그래밍(AOP) 등을 가능하게 해 준다.
객체의 제어권을 넘김으로써 개발자는 비지니스 로직 개발에 집중할 수 있게 해 준다.
2. 의존성 주입(DI)
의존성 주입(DI : Dependency Injection)이란 제어 역전의 방법 중 하나로, 사용할 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용하는 방식을 의미한다.
스프링에서 의존성을 주입받는 방법은 세 가지가 있다.
- 생성자를 통한 의존성 주입
- 필드 객체 선언을 통한 의존성 주입
- setter 메서드를 통한 의존성 주입
스프링에서는 @Autowired라는 어노테이션을 통해 의존성 주입할 수 있다. 스프링 4.3 이후 버전에선 생성자를 통한 의존성을 주입할 때 해당 어노테이션을 생략할 수 있다.
각 의존성 주입의 예제 코드를 확인해보자.
생성자주입
@RestController
public class DIController {
MyService myService;
@Autowired
public DIController(MyService myService) {
this.myService = myService;
}
@GetMapping("/di/hello")
public String getHello() {
return myService.getHello();
}
}
필드 객체 선언을 통한 주입
@RestController
public class FieldInjectionController {
@Autowired
private MyService myService;
}
setter 메서드를 통한 의존성 주입
@RestController
public class SetterInjectionController {
MyService myService;
@Autowired
public void setMyService(MyService myService) {
this.myService = myService;
}
}
스프링 공식 문서에서 권장하는 방식은 생성자를 통한 의존성을 주입이다. 다른 방식과는 다르게 생성자를 통해 의존성을 주입받는 방식은 레퍼런스 객체 없이는 객체를 초기화할 수 없게 설계할 수 있기 때문이다.
3. 관점 지향 프로그래밍(AOP)
관점 지향 프로그래밍(AOP : Aspect-Oriented Programming)은 스프링의 아주 중요한 특징이다. 자바프로그래밍에션 객체지향 프로그래밍(OOP)이 중요하다. AOP는 OOP의 기능을 보완하는 수단으로, 여러 곳에 쓰이는 공통 기능을 모듈화 하여 필요한 곳에 연결함으로써 유비보수 또는 재사용에 용이하도록 하는 것을 의미한다.
그럼 왜 OOP 기능을 보완할까?
OOP는 객체지향 원칙에 따라 관심사가 같은 데이터를 한 곳에 모아 분리하고 낮은 결합도를 갖게 하여 독립적이고 유연한 모듈로 캡슐화를 하는 것이다. 하지만 이러한 과정 중 중복된 코드들이 많아지고 가독성, 확장성, 유지보수성을 떨어뜨린다.
이러한 문제를 보완하기 위해 나온 것이 AOP이다.
AOP에서는 핵심기능과 공통기능을 분리시켜 핵심 로직에 영향을 끼치지 않게 공통기능을 끼워 넣는 개발 형태 이며 이렇게 개발함에 따라 무분별하게 중복되는 코드를 한 곳에 모아 중복 되는 코드를 제거 할 수 있어지고 공통기능을 한 곳에 보관함으로써 공통 기능 하나의 수정으로 모든 핵심기능들의 공통기능을 수정 할 수 있어 효율적인 유지보수가 가능하며 재활용성이 극대화된다.
스프링은 디자인 패턴 중 하나인 프락시 패턴을 통해 AOP 기능을 제공하고 있다.
4. 스프링 프레임워크의 다양한 모듈
스프링 프레임워크는 기능별로 구분된 약 20개의 모듈로 구성되어 있다. 버전별로 차이가 약간의 차이가 있지만 큰 틀은 비슷하다. 그리고 스프링 프레임워크를 사용한다고 해당 다이어그램의 모든 모듈을 사용할 필요는 없다. 우리가 필요한 모듈만 선택해서 사용하게끔 설계가 가능하며, 이를 경량 컨테이너 설계라고 한다.
스프링 프레임워크 vs 스프링 부트
앞서 확인했듯이 스프링 프레임워크는 기본 개발 방식의 문제와 한계를 극복하기 위해 많은 기능을 제공합니다. 하지만 많은 기능을 제공함에 따라 설정이 복잡한 편입니다.
실제로 필요한 모듈들을 추가하다 보면 설정이 매우 복잡해진다. 이러한 문제를 해결하기 위해 등장한 것이 스프링 부트(Spring Boot)이다.
즉, 스프링 부트를 이용하면 별도의 복잡한 설정 없이 스프링 기반 애플리케이션을 손쉽게 만들 수 있다.
이제는 스프링 프레임워크랑 비교했을 때 스프링 부트가 가진 특징을 알아보자.
스프링 부트의 특징
1. 의존성 관리
스프링 프레임워크에서는 개발에 필요한 각 모듈의 의존성을 직접 설정해야 한다. 또 호환되는 버전을 명시해 줘야 정상 동작한다. 그렇기 때문에 만약 스프링 프레임워크나 라이브러리 버전을 올리는 상황에서는 다른 라이브러리 버전까지 고려해야 한다.
하지만 스프링 부트는 'spring-boot-starter'라는 의존성을 제공한다. spring-boot-starter의 의존성을 여러 종류가 있고, 각 라이브러리 기능과 관련된 자주 사용되고 서로 호환되는 버전을 제공해 준다. 이를 통해 위해서 발생하는 호환성 이슈를 해결할 수 있다.
많이 사용되는 spring-boot-starter 라이브러리를 소개한다.
- spring-boot-starter-web : 스프링 MVC를 사용하는 RESTful 애플리케이션을 만들기 위한 의존성이며, 기본으로 내장 톰캣이 포함돼 있어 jar 형식으로 실행 가능하다.
- spring-boot-starter-test : JUnit, Jupiter, Mockito 등의 테스트용 라이브러리를 포함한다.
- spring-boot-starter-jdbc : HikariCP 커넥션 풀을 활용한 JDBC 기능을 제공한다.
- spring-boot-starter-security : 스프링 시큐리티(인증, 권한, 인가 등) 기능을 제공한다.
- spring-boot-starter-date-jpa : 하이버네이트를 활용한 JPA 기능을 제공한다.
- spring-boot-starter-cache : 스프링 프레임워크의 캐시 기능을 지원한다.
2. 자동설정(AutoConfiguration)
자동설정은 애플리이케이션에 추가된 라이브러리를 실행하는데 필요한 환경 설정을 알아서 찾아준다. 예를 들면 개발에 필요한 디펜던시(Depandency)를 추가하면 프레임워크에서 이를 자동으로 관리해 준다.
스프링 프레임워크의 문제 중 하나가 초기에 필요한 빈들을 수동으로 등록해줘야 한다는 점이다.
스프링 부트는 이러한 문제를 해결하기 위해 자동 구성(Auto Configuration)이라는 필요한 빈들을 자동으로 등록해주는 기능을 제공한다.
스프링부트 프로젝트를 보면 @SpringBootAppliCation 어노테이션이 있는 것을 확인할 수 있다. 이 어노테이션의 역할은 스프링 부트 애플리케이션이 실행되면 @Component 시리즈 어노테이션이 붙은 클래스를 발견해 빈(Bean)으로 등록한다. 이후 @EnableAutoConfiguration 어노테이션을 통해 자동설정 된다.
이렇게 등록된 설정들은 @Confitional의 조건을 충족할 경우 빈에 등록되고 애플리케이션의 자동 반영된다.
spring-boot-autoconfigure 패키지의 spring.factories 파일을 확인하면 자동 설정된 항목을 확인할 수 있다.
3. 내장 WAS
스프링 부트의 각 웹 애플리케이션에는 내장 WAS가 존재한다. 기본적으로 톰캣이 내장되며 필요에 따라 다른 웹서버(Jetty, Undertow 등)로 대체할 수 있다.
4. 모니터링
개발이 끝나고 서비스를 운영하는 시기에는 해당 시스템이 사용하는 스레드, 메모리, 세션 등의 주요 요소를 모니터링해야 한다. 스프링부트는 스프링 액추에이터(Spring Actuator)라는 자체 모니터링 도구를 제공한다.
정리
1. DI 의존성 종류 3가지 사용법 정리
2. AOP 사용법 정리
3. 스프링 액추에이터 사용법 정리
스프링 프레임워크와 스프링 부트의 차이점을 나타내는 것이 주목적이라
위 세 가지 항목은 자세히 다루지 않아 추가적으로 공부를 진행하여 정리하자.
Reference
'Framework > Spring' 카테고리의 다른 글
[Spring] POST, PUT, DELETE API (0) | 2023.10.11 |
---|---|
[Spring] GET API를 구현하는 다양한 방법 (0) | 2023.10.06 |
[Spring] REST API 란? (0) | 2023.10.05 |
[Spring] 레이어드 아키텍처와 스프링의 레이어드 아키텍처 (0) | 2023.10.05 |
[Spring] 스프링 부트의 동작 방식 (0) | 2023.10.05 |