자바의 웹 프레임워크로 기존 스프링(Spring) 프레임워크에 톰캣 서버를 내장하고 여러 편의 기능들을 추가한 프레임워크이다.
웹 프레임워크란 웹 프로그램을 만들기 위한 기능(쿠키나 세션 처리, 로그인/로그아웃 처리, 권한 처리, 데이터베이스 처리 등)을 가지고 있는 스타터 키트라고 생각하면 된다.
스프링만 사용하여 웹 애플리케이션을 개발한다면 톰캣과 같은 WAS(Web Application Server)가 필요한데 톰캣 서버가 내장되어 있고 설정도 자동 적용되기 때문에 신경쓸 필요가 없다.
보안 기능도 포함되어 있는데 SQL 인젝션, XSS(cross-site scripting), CSRF(cross-site request forgery), 클릭재킹(clickjacking)과 같은 보안 공격을 기본으로 막아 준다.
- SQL 인젝션은 악의적인 SQL을 주입하여 공격하는 방법이다.
- XSS는 자바스크립트를 삽입해 공격하는 방법이다.
- CSRF는 위조된 요청을 보내는 공격 방법이다.
- 클릭재킹은 사용자의 의도하지 않은 클릭을 유도하는 공격 방법이다.
자바 프로그래밍을 하기 위해 필수적으로 필요한 JDK를 설치한다. JDK는 Java Development Kit
의 약자이다.
만약 위 URL이 더이상 유효하지 않다면 구글 검색창에서 "JDK Download" 로 검색하고 들어가면 된다.
STS는 스프링부트 프로그램 작성을 도와주는 도구이다. IDE(Intergrated Development Environment), 통합개발환경이라고 부른다. STS는 이클립스 기반으로 제작된 스프링 개발에 최적화된 에디터이다. 인텔리제이나 이클립스도 많이 사용된다.
STS 설치 파일 주소: https://spring.io/tools
설치한 후 "Create new Spring Starter Project"를 눌러 프로젝트를 생성한다.
이 부분은 중요하므로 주의깊게 입력하자.
다음은 스프링부트 버전을 선택하는 화면인데 버전이름 뒤에 다른 말이 붙지 않은 안정화 버전 중에 최신 버전을 사용했고, Available 항목에서 web을 입력하여 "Spring Web" 항목을 찾아서 선택한다.
"Spring Web"을 선택하지 않고 지나치면 웹 기능을 사용할 수 없으니 실수하지 않도록 주의하자.
http://localhost:8080/hello
와 같은 브라우저의 요청을 처리하기 위해서는 컨트롤러가 필요하다. 컨트롤러는 서버에 전달된 클라이언트의 요청(URL과 전달된 파라미터 등)을 처리하는 자바 클래스이다.
package com.mysite.sbb;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "Hello World";
}
}
@Controller
애너테이션은 HelloController 클래스가 컨트롤러의 기능을 수행한다는 의미이다. 이 애너테이션이 있어야 스프링부트 프레임워크가 컨트롤러로 인식한다.
@RequestMapping("/hello")
애너테이션은 http://localhost:8080/hello URL 요청이 발생하면 hello 메서드가 실행됨을 의미한다. 즉, /hello URL과 hello 메서드를 매핑하는 역할을 한다.
URL명과 메서드명은 동일할 필요는 없다. 즉 /hello URL일 때 메서드명을 hello가 아닌 hello2와 같이 해도 상관없다.
@ResponseBody
애너테이션은 hello 메서드의 응답 결과가 문자열 그 자체임을 나타낸다. hello 메서드는 "Hello World" 라는 문자열을 리턴하므로 출력으로 "Hello World" 문자열이 나갈 것이다. 단순한 문자열 보다는 HTML 파일과 같은 템플릿을 주로 사용한다.
다음으로는 스프링부트 개발을 도와주는 도구들에 대해 알아본다
Spring Boot Devtools
Live Reload
롬복
- 롬복 설치
- Getter, Setter
- RequiredArgsConstructor
프로그램이 변경 되더라도 로컬서버가 변경된 클래스를 리로딩하지 않기 떄문에 수정하고 변경된 사항을 확인하려면 매번 서버를 재시작 해야 하는데, Spring Boot Devtools를 사용하면 서버 재시작 없이도 클래스 변경시 서버가 자동으로 재기동 된다.
plugins {
id 'org.springframework.boot' version '2.6.4'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.mysite'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
}
tasks.named('test') {
useJUnitPlatform()
}
사용하기 위해서는 그레이들(Gradle)로 설치해야 하는데 build.gradle 파일의 dependencies 항목에 developmentOnly 'org.springframework.boot:spring-boot-devtools'
를 추가해준다.
developmentOnly
Gradle의 developmentOnly는 개발환경에만 적용되는 설정이다. 즉, 운영환경에 배포되는 jar, war 파일에는 developmentOnly로 설치된 라이브러리는 제외된다.
build.gradle 파일의 내용을 적용하려면 파일을 오른쪽 마우스 버튼을 눌러 [Gradle -> Refresh Gradle Project]
를 선택하여 필요한 라이브러리를 다운로드해야 한다.
설치가 완료되면 Boot Dashboard의 서버명에[devtools]가 붙은 것을 확인할 수 있다. 이후 서버를 재시작하면 준비완료이다.
Spring Boot Devtools를 통해 수정사항이 서버에 잘 적용되는 것은 확인할 수 있었지만 브라우저에서는 URL을 다시 호출하던가 Refresh를 해야만 확인할 수 있었는데 Spring Boot Devtools
의 Live Reload
기능을 통해 크롬에서만 브라우저 재호출 없이 변경 사항을 확인할 수 있다.
크롬 브라우저에서 LiveReload++ 확장 프로그램을 설치하고 적용해주면 된다.
롬복은 자바 클래스에 Getter, Setter, 생성자 등을 자동으로 만들어 주는 도구이다.
프로젝트를 진행하면서 데이터를 처리하기 위한 엔티티 클래스나 DTO 클래스등을 사용해야 하는데 이때 클래스의 속성들에 대한 Getter, Setter를 만들어야 한다.
물론 Getter, Setter 메서드를 직접 만들어도 되지만 롬복(lombok)을 사용하면 좀 더 깔끔한 소스코드를 만들수 있다.
롬복을 사용하려면 플러그인을 먼저 설치 해야한다.
다운로드한 lombok.jar 파일을 실행시키고 다음과 같은 순서로 롬복을 설치한다.
1. "Specify location"을 눌러 롬복 플러그인을 사용할 IDE인 STS가 설치된 경로를 선택한다.
2. "Install / Update"를 눌러 롬복 플러그인을 설치한다.
3. "Quit Installer"를 눌러 설치 프로그램을 종료한다.
그리고 STS를 종료하고 재시작한 후 build.gradle 파일의 dependencies{} 안에 다음 코드를 추가해준다.
(...생략...)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
// 추가된 코드 ->
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// <-
}
(...생략...)
롬복 관련 라이브러리를 설치하고 컴파일시 롬복이 적용되도록 했다.
build.gradle 파일을 수정한 후에는 반드시 프로젝트에 우클릭을 해서 [Gradle -> Refresh Gradle Project]
를 선택하여 라이브러리를 다운로드 해야 한다.
compileOnly
build.gradle 파일의 compileOnly는 해당 라이브러리가 컴파일 단계에서만 필요한 경우에 사용한다.
annotationProcessor
컴파일 단계에서 애너테이션을 분석하고 처리하기 위해 사용한다.
다음처럼 HelloLombok 클래스를 작성하여 롬복이 정상적으로 동작하는지 확인해본다.
아래 코드 작성시 오류가 없어야 한다.
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 메서드가 실제로 포함된다
이번에는 HelloLombok 클래스를 다음과 같이 수정해 보자.
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 애너테이션을 적용하면 해당 속성을 필요로하는 생성자가 롬복에 의해 자동으로 생성된다. (※ final이 없는 속성은 생성자에 포함되지 않는다.)
final을 적용했기 때문에 @Setter는 의미가 없으며 Setter 메서드들도 사용할수 없다. final은 한번 설정한 값을 변경할수 없게 하는 키워드이다.
즉, 다음과 같이 생성자를 직접 작성한 경우와 동일하다.
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());
}
}
@RequiredArgsConstructor 애너테이션은 이후 진행되는 챕터에서 의존성 주입(Dependency Injection)시 사용된다.
DI(Dependency Injection) - 스프링이 객체를 대신 생성하여 주입한다.