Spring Boot 기반으로 Spring 프로젝트를 만들어주는 spring initializr를 통해 프로젝트를 생성한다.
프로젝트는 다음과 같이 선택하면 된다.
- Project: Gradle - Groovy
- Spring Boot: 3.0.0 이상 (정식 릴리즈된 버전으로 선택하기)
- Language: Java
- Packaging: Jar
- Java: 17 or 21
Project Metadata
- groupid: 도메인명을 작성
- artifact: 빌드되어 나올 때의 결과물 즉, 프로젝트명
Dependencies
- Spring Web: 웹 프로젝트를 만들기 위해 선택해야 하는 dependency
- Thymeleaf: HTML을 만들어줄 템플릿 엔진
여기서 잠깐⚠️ Project 선택 시 Maven과 Gradle 둘 중 하나를 선택할 수 있는데 왜 Gradle을 선택할까?
Maven과 Gradle은 빌드 관리 도구인데 아래와 같은 이유로 Gradle이 더 뛰어난 성능을 보인다.
1. 빠른 빌드 속도: Gradle은 Maven보다 빌드와 테스트 실행 결과가 더 빠르다. 또한 Gradle은 캐시를 사용해 테스트 반복 시 실행 결과 시간의 차이가 더 커진다.
2. 스크립트 품질의 차이: Gradle은 Groovy를 사용해 동적인 빌드는 Groovy 스크립트로 플러그인을 호출하거나 직접 코드를 작성할 수 있다.
참고: https://hyojun123.github.io/2019/04/18/gradleAndMaven/
위의 그림과 같이 설정해주고 generate 해 폴더를 다운로드하였다.
IntelliJ에서 다운로드한 것을 import 해주는데 build.gradle 파일(버전 설정하고 라이브러리 가져오는 역할)을 선택 후 Open as Project 버튼을 통해 프로젝트로써 파일을 열어준다.
여기서 잠깐⚠️ 다운로드한 파일 전체를 IntelliJ에서 오픈할 수 있는데 왜 build.gradle 파일을 선택해 프로젝트를 오픈하는 걸까?
그 이유는 가끔 프로젝트를 열 때, Gradle 프로젝트로 인식하지 못하는 경우가 있어 build.gradle 파일로 프로젝트를 열어 이런 상황을 방지하고자 하는 것이었다!
참고: 인프런 질문 게시판
코드 작성하기에 앞서 build.gradle 파일에 대해 간단하게 알아보자!
Gradle은 의존성 관리를 위한 빌드 도구로 build.gradle에서 눈여겨봐야 할 곳은 의존성과 관련된 부분이다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.1'
id 'io.spring.dependency-management' version '1.1.5'
}
group = 'com.youjava'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
// 라이브러리 다운 받는 레포지토리 설정
// 필요 시 특정 사이트의 url 작성
repositories {
mavenCentral()
}
// 선택한 라이브러리 목록
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
의존성은 dependencies 블록 내에 선언하고, Gradle은 선언된 의존성을 자동으로 다운로드하고, 빌스와 테스트에 사용한다.
repositories 메서드
- 저장소 설정 담당
- mavenCentral(): 기본적으로 라이브러리를 다운로드하는 default repository
- maven: 필요한 repository를 가져와야 할 때 사용
dependencies 메서드
- 의존성 라이브러리 추가 시 사용
- implementation: 의존 라이브러리 수정 시 본 모듈까지만 재빌드
- testImplementation: 테스트 코드를 수행할 때만 적용
- api: 의존 라이브러리 수정 시 본 모듈을 의존하는 모듈들 전부 재빌드
아직은 시작 단계이니 이 정도까지만 알아두고 점차 공부하는 것으로 하자
Spring Boot 프로젝트를 실행하기에 앞서 HelloSpringApplication.java 코드를 알아보자!
package com.youjava.hello_spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloSpringApplication {
public static void main(String[] args) {
SpringApplication.run(HelloSpringApplication.class, args);
}
}
main 메서드를 실행하면 SpringApplication.run 안에 지정된 클래스인 HelloSpringApplication이 실행되고, @SpringBootApplication 어노테이션으로 인해 Spring Boot Application이 실행된다. 이때 tomcat이라는 웹서버를 자체적으로 띄우면서 Spring Boot가 같이 실행이 되는 것이다.
HelloSpringApplication.java를 실행시켜 보면 아래의 그림과 같이 Tomcat started on port 8080 문구를 볼 수 있다.
localhost:8080을 실행해 보면 아래와 같은 페이지를 볼 수 있는데 아직 코드를 작성해 놓은 것이 없어 error가 뜨는 것이다.
이제 간단한 Welcome Page를 만들어 볼 것인데, Welcome Page를 위한 코드를 작성하기 전 Spring Boot의 Welcome Page 동작 방식을 살펴보자!
Spring Boot는 static과 template의 welcome page를 모두 제공하는데, static의 index.html을 가장 먼저 실행하고, static의 index.html을 찾을 수 없으면 template의 index 파일을 확인한다. static와 template에서 index 파일을 찾을 수 없으면 자동적으로 애플리케이션의 welcome page를 사용하는 동작 방식을 가지고 있다.
📂 resources/static/index.html
<!DOCTYPE HTML>
<html>
<head>
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
Hello
<a href="/hello">hello</a>
위와 같이 static의 index.html 파일을 작성해주었다.
해당 html 코드는 hello 문구를 클릭하면 /hello로 페이지가 이동하는 코드이다. 하지만 아직 /hello 페이지 코드를 작성하지 않아 클릭 시에는 아래와 같이 error 페이지를 반환한다.
이제 Web Controller를 만들어 지정된 뷰에 모델 객체를 넘겨주고 화면에 띄울 것이다.
여기서 잠깐⚠️ Spring Boot의 Controller란?
Spring 프레임워크는 MVC 패턴을 채택한다.
MVC 패턴은 Model View Controller의 줄임말로, Controller가 View(화면)와 Model(비즈니스 로직)을 연결시켜주는 다리 역할을 한다. 예를 들어 /hello로 가달라는 사용자의 요청이 들어오면 어디로 갈지 맞는 길을 안내하는 것이다.
Controller의 역할을 수행하기 위해서는 @Controller annotation을 사용한다. 해당 어노테이션을 사용하면 Spring 프레임워크에 해당 클래스를 Controller로 사용한다고 알리게 된다.
참고: https://goddaehee.tistory.com/203 , https://luanaeun.tistory.com/200
controller를 모아 놓는 디렉토리를 먼저 만들 것이다.
위와 같이 src/main/java/domain명/controller 디렉토리를 만들고
해당 디렉토리에 HelloController.java를 만들어 Controller 역할을 수행하는 클래스를 만든다.
package com.youjava.hello_spring.controller;
import org.springframework.ui.Model;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("hello")
public String hello(Model model){
model.addAttribute("data", "hello!");
return "hello"; //templates의 hello.html 실행
}
}
model에 hello!라는 데이터를 만들고 templates의 hello.html을 실행하도록 반환값을 설정해주었다.
templates의 hello.html는 다음과 같이 작성해주었다.
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕하세요. ' + ${data}" >안녕하세요. 손님</p>
</body>
</html>
Thymeleaf 템플릿 엔진을 사용하기 위해 상단에 <html xmlns:th="http://www.thymeleaf.org"> 를 작성해주었다.
해당 코드의 결과는 아래와 같다.
HelloController.java에서 Model에 설정해준 data가 웹 페이지에 보여지는 것을 확인할 수 있다.
동작 환경 그림을 보며 동작 방식을 이해해보겠다.
- 컨트롤러에서 리턴 값으로 반환한 화면을 viewResolver가 찾아서 처리한다.
- resources: templates/ + {viewName} + .html
그렇다면 이제 intelliJ IDE에서만 실행하는 것이 아닌 build 파일을 만들어 build 파일로 실행하는 방법을 알아보자!
mac을 기준으로 작성해보면
1. 터미널 이동
2. Spring Boot 프로젝트가 있는 경로로 이동
3. ./gradlew build
4. cd build/libs
5. java -jar [만들어진 jar 파일 이름]
jar 파일을 이용해 서버를 실행할 수 있다!
여기서 잠깐⚠️ ./gradlew build 시 왜 jar 파일이 두 개가 생성될까?
./gradlew build 시 hello-spring-0.0.1-SNAPSHOT.jar와 hello-spring-0.0.1-SNAPSHOT-plain.jar이 생기는 것을 확인할 수 있다.
executable archive vs plain archive
- executable archive: jar 파일은 bootJar 테스크에서 생성된 아카이브
- plain archive: plain.jar 파일은 jar 테스크에서 생성된 아카이브
- plain archive는 어플리케이션 실행에 필요한 모든 의존성을 포함하고 있지 않고, 작성된 코드의 클래스 파일과 리소스 파일만 포함해 plain archive로 java -jar을 실행하면 에러가 발생한다.
빌드 시 plain archive가 생성되지 않도록 하기 위해서는 아래 코드를 build.gradle에 추가해주면 된다!
tasks.named("jar") { enabled = false }
** 해당 포스팅은 인프런의 김영한 님 강의 중 스프링 입문-코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 토대로 작성했습니다
'Spring & SpringBoot' 카테고리의 다른 글
HTTP 웹 기본 지식 (1) - 인터넷 네트워크, 웹 브라우저 요청 흐름, HTTP 기초 (1) | 2024.08.23 |
---|---|
[Spring 입문] Spring 웹 개발 기초 (정적 컨텐츠, MVC와 템플릿 엔진, API) (0) | 2024.07.25 |