스프링 부트(Spring Boot)는 웹 프로그램(웹 애플리케이션)을 쉽고 빠르게 만들 수 있도록 도와주는 자바의 웹 프레임워크이다. 스프링 부트는 스프링(Spring) 프레임워크에 톰캣(Tomcat)이라는 서버를 내장하고 여러 편의 기능들을 추가하여 개발자들 사이에서 꾸준히 인기를 누리고 있다.
톰캣은 클라이언트의 요청을 해석하여 그에 맞는 자바 프로그램을 실행한 후 그 결과를 응답해 주는 웹 어플리케이션 서버이다.
웹 프로그램을 완성하기 위해서는 많은 기능을 생성해야 한다. 예를 들어 쿠키나 세션 처리, 로그인/로그아웃 처리, 권한 처리, 데이터베이스 처리 등 웹 프로그램을 완성하기 위해 만들어야 할 기능이 많다. 하지만 웹 프레임워크에는 이런 기능들이 만들어져 있기 때문에, 본인이 이런 기능들을 일일이 만들 필요가 없다. 쉽게 말해 웹 프레임워크는 웹 프로그램을 만들기 위한 스타터 키트라고 생각하면 된다. 그리고 자바로 만든 웹 프레임워크 중 하나가 바로 스프링 부트이다.
스프링 부트의 몇 가지 규칙만 익히면 기존에 자바로 웹 프로그램을 작성하는 방식보다 빠르게 웹 프로그램을 만들 수 있다. 크롬이나 사파리와 같은 웹 브라우저에 ‘Hello World’를 출력하려면 다음과 같은 클래스 하나만 작성하면 된다.
@Controller
public class HelloController {
@GetMapping("/")
@ResponseBody
public String hello() {
return "Hello World";
}
}
스프링 부트는 튼튼한 웹 프레임워크이다
스프링 부트를 사용하면 아래와 같은 보안 공격을 막아 주는 코드를 직접 짤 필요가 없다.
스프링 부트에는 여러 기능이 준비되어 있다
스프링 부트에는 아래와 같이 웹 프로그램을 개발하는 데 필요한 도구와 기능이 대부분 준비되어 있다.
스프링 부트는 WAS가 필요없다
스프링 부트 대신 스프링만 사용하여 웹 애플리케이션을 개발한다면 실행할 수 있는 톰캣과 같은 WAS(Web Application Server)가 필요하다. 하지만 스프링 부트에는 톰캣 서버가 내장되어 있고 설정도 자동 적용된다.
WAS란?
WAS는 웹 애플리케이션과 서버 환경을 연결하는 중간 역할을 하는 소프트웨어 플랫폼이다. 예를 들어 사용자가 웹 브라우저로 서버에 요청을 보내면 WAS는 사용자의 요청을 해석하여 그에 맞는 서버 프로그램을 구동한 후 그 결과를 사용자에게 보여준다. WAS의 종류로는 아파치 톰캣, 오라클 웹 로직, IBM 웹스피어, 제이보스, 제우스 등이 있다.
스프링 부트는 설정이 쉽다
스프링 부트가 등장하기 전 개발자들은 스프링을 사용하여 웹 애플리케이션을 개발했다. 스프링은 설정이 복잡하며, 한번 설정한 기능 등도 스프링의 버전업으로 변경되거나 없어지는 일이 비일비재했다. 하지만 스프링 부트는 스프링의 복잡한 설정을 자동화, 단순화하여 누구나 쉽게 스프링을 사용할 수 있도록 한 프레임워크이다.

클라이언트는 브라우저를 말하고, 서버는 브라우저로 접속 가능한 원격 컴퓨터를 의미한다.

크롬 브라우저에서 서버에 요청을 보낼 때는 서버의 주소(IP 주소) 또는 서버의 주소를 대체할 수 있는 도메인명을 알아야 한다. 웹 서버는 요청에 대한 응답으로 HTML 문서나 다른 리소스들을 브라우저에 표시한다.
서버는 브라우저로 접속할 수 있는 웹 서비스뿐만 아니라 FTP, 이메일 서비스 등도 운용할 수 있다. 하지만 포트로 서비스들을 구분할 수 있기 때문에 보통 서비스별로 다른 IP 주소를 사용하지는 않는다. 포트(port)는 네트워크 서비스를 구분하는 번호로, 하나의 서버 주소에서 포트를 사용하여 매우 많은 서비스를 운용할 수 있는데, 대표적인 서비스의 종류는 다음과 같다.
| 프로토콜 | 서비스 내용 | 포트 |
|---|---|---|
| HTTP | 웹 서비스 | 80 |
| HTTPS | SSL을 적용한 웹 서비스 | 443 |
| FTP | 파일 전송 서비스 | 21 |
| SSH, SFTP | 보안이 강화된 TELNET, FTP 서비스 | 22 |
| TELNET | 원격 서버 접속 서비스 | 23 |
| SMTP | 메일 전송 서비스 | 25 |
위 표에 있는 포트 번호는 기본 포트 번호로, 클라이언트나 서버 등에서는 대부분 이 번호를 기본값으로 설정한다. 하지만 필요에 따라 포트 번호를 별도로 정의하고 변경할 수 있다. 예를 들어 HTTP의 포트를 80 대신 8080을 사용할 수도 있다.
브라우저 주소 창에 naver.com 대신 naver.com:443을 입력하여도 동일하게 동작하는 것을 볼 수 있다.
localhost라는 도메인명은 127.0.0.1이라는 IP 주소를 의미하며, 127.0.0.1 IP 주소는 내 컴퓨터를 의미한다. 그리고 8080은 8080번 포트로 서비스를 운용한다는 의미이다.
http://localhost:8080/hello와 같은 브라우저의 요청을 처리하려면 먼저 컨트롤러(controller)가 필요하다. 컨트롤러는 서버에 전달된 클라이언트의 요청을 처리하는 자바 클래스이다.
package com.mysite.sbb;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String hello() {
return "Hello World";
}
}
자바의 애너테이션(annotation)이란 자바의 클래스, 메서드, 변수 등에 정보를 부여하여 부가 동작을 할 수 있게 하는 목적으로 사용한다.
@Controller 애너테이션은 HelloController 클래스가 컨트롤러의 기능을 수행한다는 의미이다.
hello 메서드에 적용된 @GetMapping(”/hello”) 애너테이션은 http://localhost:8080/hello URL 요청이 발생하면 hello 메서드가 실행됨을 의미한다. 즉, /hello URL과 hello 메서드를 매핑하는 역할을 한다. 이때 URL명과 메서드명이 동일할 필요는 없다.
또한 Get 방식의 URL 요청을 위해 GetMapping을 사용하고 Post 방식의 URL 요청을 위해서는 PostMapping을 사용한다. 그리고 @ResponseBody 애너테이션은 hello 메서드의 출력 결과가 문자열 그 자체임을 나타낸다. hello 메서드는 ‘Hello World’ 문자열을 리턴하므로 결과로 ‘Hello World’ 문자열이 출력된다.
Get 방식과 Post 방식은 어떻게 다를까?
Get과 Post는 HTTP 프로토콜을 사용하여 데이터를 서버로 전송하는 주요 방식이다.
- Get: 데이터를 URL에 노출시켜 요청하며, 주로 서버에서 데이터를 조회하거나 읽기 위한 목적으로 사용
- Post: 데이터를 숨겨서 요청하므로 로그인 정보와 같은 민감한 데이터를 서버에 제출하거나 저장하는 목적으로 사용


Spring Boot Devtools를 설치하면 서버를 재시작하지 않아도 클래스를 변경할 때 서버가 자동으로 재가동된다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
**developmentOnly 'org.springframework.boot:spring-boot-devtools'**
}

롬복(lombok) 라이브러리는 소스 코드를 작성할 때 자바 클래스에 애너테이션을 사용하여 자주 쓰는 Getter 메서드, Setter 메서드, 생성자 등을 자동으로 만들어 주는 도구이다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
**compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'**
}
// HelloLombok.java
package com.mysite.sbb;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class HelloLombok {
private String hello;
private int lombok;
public static void main(String[] args) {
HelloLombok helloLombok = new HelloLombok();
helloLombok.setHello("헬로");
helloLombok.setLombok(5);
System.out.println(helloLombok.getHello());
System.out.println(helloLombok.getLombok());
}
}
HelloLombok 클래스에 ‘hello’, ‘lombok’ 이렇게 2개의 속성을 추가한 후 클래스명 바로 위에 @Getter, @Setter 애너테이션을 적용했더니 Getter와 Setter 메서드를 따로 작성하지 않아도 setHello, setLombok, getHello, getLombok 등의 메서드를 사용할 수 있게 되었다.
소스 코드에는 Getter, Setter 메서드가 눈으로 보이지 않지만 컴파일 단계에서 롬복이 대신 생성해 주므로 컴파일된 클래스에는 Getter와 Setter 메서드가 실제로 포함된다.
아래 코드는 Getter, Setter 메서드를 직접 작성한 코드이다.
package com.mysite.sbb;
public class HelloLombok {
private String hello;
private int lombok;
public void setHello(String hello) {
this.hello = hello;
}
public void setLombok(int lombok) {
this.lombok = lombok;
}
public String getHello() {
return this.hello;
}
public int getLombok() {
return this.lombok;
}
public static void main(String[] args) {
HelloLombok helloLombok = new HelloLombok();
helloLombok.setHello("헬로");
helloLombok.setLombok(5);
System.out.println(helloLombok.getHello());
System.out.println(helloLombok.getLombok());
}
}
// HelloLombok.java
package com.mysite.sbb;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public class HelloLombok {
private final String hello;
private final int lombok;
public static void main(String[] args) {
HelloLombok helloLombok = new HelloLombok("헬로", 5);
System.out.println(helloLombok.getHello());
System.out.println(helloLombok.getLombok());
}
}
위와 같이 hello, lombok 속성에 final을 추가하고 @RequiredArgsConstructor 애너테이션을 적용하면 해당 속성을 필요로 하는 생성자가 롬복에 의해 자동으로 생성된다.
아래 코드는 생성자를 직접 작성한 코드이다.
package com.mysite.sbb;
import lombok.Getter;
@Getter
public class HelloLombok {
private final String hello;
private final int lombok;
// 롬복을 사용하지 않는다면 이와 같이 생성자를 직접 작성해야 한다.
public HelloLombok(String hello, int lombok) {
this.hello = hello;
this.lombok = lombok;
}
public static void main(String[] args) {
HelloLombok helloLombok = new HelloLombok("헬로", 5);
System.out.println(helloLombok.getHello());
System.out.println(helloLombok.getLombok());
}
}
// HelloController.java
package com.mysite.sbb;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@GetMapping("/jump")
@ResponseBody
public String hello() {
return "점프 투 스프링 부트";
}
}

// Book.java
package com.mysite.sbb;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Book {
private String title;
private String author;
}