목적
- Gradle을 이용하여 프로젝트를 빌드하고 실행하기
따라하기
- Gradle이 빌드할 Java 프로젝트를 설정
- IntelliJ에서 New Project를 통해 프로젝트 생성 가능
Q. Gradle vs Maven
- New Project로 프로젝트를 생성하는 중 Gradle과 Maven의 차이가 궁금해졌다.
A. Gradle과 Maven은 모두 빌드 관리 도구(Build Tool)
- Build(빌드) : 소스코드 파일을 컴퓨터에서 실행할 수 있는 독립적인 형태로 변환하는 과정과 결과를 말함
- 우리가 작성한 소스코드를 프로젝트에서 쓰인 각각의 파일 및 자원을 JVM이나 톰캣 같은 WAS가 인식할 수 있도록 패키징하는 과정 및 결과물
- Build-Tool : 소스코드에서 애플리케이션을 생성하면서 여러가지 외부 라이브러리를 사용하는데, 빌드 관리도구는 사용자가 관리할 필요 없이 필요한 라이브러리들을 자동으로 관리
- 종속성 다운로드 - 전처리 (Preprocessing)
- 소스코드를 바이너리 코드로 컴파일 (Compile)
- 바이너리 코드를 패키징 (Packaging)
- 테스트 실행 (Testing)
- 프로덕션 시스템에 배포 (distribution)
Maven vs Gradle
- Maven : Java 전용 프로젝트 관리 도구, Lifecycle 관리 목적 빌드 도구 (Apache 라이센스로 배포되는 오픈 소스 소프트웨어)
- Gradle : Maven을 대체할 수 있는 프로젝트 구성 관리 및 범용 빌드 툴, Ant Builder와 Groovy script를 기반으로 구축되어 기존 Ant의 역할과 배포 스크립의 기능을 모두 사용가능하며 스프링부트와 안드로이드에서 사용된다.
- 빌드 속도가 Maven에 비해 10배 ~ 100배 가량 빠르며, Java, C/C++, Python 등을 지원
- Groovy는 JVM에서 실행되는 스크립트 언어
- JVM에서 동작하지만 소스코드를 컴파일할 필요는 없음
- Java와 호환되며, Java class file들을 Groovy class로 사용 가능
- Java 문법과 유사하여 빌드 처리를 관리할 수 있음
- Gradle의 특징에는 가독성 좋음(간결한 정의), 재사용 용이(설정 주입 방식 - Configuration Injection), 구조적인 장점(Build Script를 Groovy기반의 DSL(Domail Specific Language)를 사용), 편리함(Gradle 설치 없이, Gradle wrapper를 이용하여 빌드 지원), 멀티 프로젝트(멀티 프로젝트 빌드를 지원하기 위해 설계된 빌드 관리 도구), 지원(Maven을 완전히 지원) 이 있다.
- 스크립트 길이와 가독성 면에서는 gradle이 우세
- 빌드와 테스트 실행 결과 Gradle이 더 빠름
- gradle은 캐시를 사용하므로, 테스트 반복 시 실행 결과 시간의 차이가 더 커짐
- 의존성이 늘어날 수록 스크립트 품질의 차이가 커짐
- Maven은 멀티 프로젝트에서 특정 설정을 다른 모듈에서 사용하려면 상속 받아야 함
- Gradle은 설정 주입 방식 사용하므로 멀티 프로젝트에 적합
참고 링크
Q. JAR vs WAR
외장 서버 vs 내장 서버
- 외장 서버 (전통적인 방식)
- 과거에 자바로 웹 애플리케이션을 개발할 때는 먼저 서버에 톰캣 같은 WAS (웹 애플리케이션 서버)를 설치
- WAS에서 동작하도록 서블릿 스펙에 맞추어 코드를 작성하고, WAR 형식으로 빌드해서 war 파일을 만든 뒤, war 파일을 was에 전달해서 배포하는 방식으로 전체 개발 주기가 동작
- WAS 기반 위에서 개발하고 실행해야 하기 때문에 IDE 같은 개발 환경에서도 WAS와 연동해서 실행되도록 복잡한 추가 설정이 필요
- 내장 서버 (최근 방식)
- 최근에는 스프링 부트가 내장 톰캣을 포함
- 애플리케이션 코드 안에 톰캣 같은 WAS가 라이브러리로 내장되어 있음
- 개발자는 코드만 작성하고 JAR로 빌드한 후, 해당 JAR를 원하는 위치에서 실행하기만 하면 WAS도 함께 실행
- main()만 실행하면 된다. WAS 설치나 IDE 같은 개발 환경에서 WAS와 연동하는 복잡한 일은 수행하지 않아도 됨
- JAR (Java Archive) : 클래스와 관련 리소스를 압축한 단순한 파일
- 자바는 여러 클래스와 리소스를 묶어서 JAR라고 하는 압축 파일을 만든다. JVM 위에서 직접 실행되거나 또는 다른 곳에서 사용하는 라이브러리로 제공
- WAR (Web Application Archive) : 웹 애플리케이션 서버 (WAS)에 배포할 때 사용하는 파일
- JAR 파일이 JVM 위에서 실행된다면, WAR는 웹 애플리케이션 서버 위에서 실행
- HTML과 같은 정적 리소스와 클래스 파일을 모두 함께 포함 (JAR와 비교해서 구조가 더 복잡, WAR 구조를 지켜야 함)
- WAR의 구조는 **WEB-INF** 폴더를 기준으로 나뉜다.
- WEB-INF : 자바 클래스와 라이브러리, 그리고 설정 정보가 들어가는 곳
- classes (실행 클래스 모음), lib(라이브러리 모음), web.xml(웹 서버 배칠 설정 파일 - 생략 가능)
- 그 외 영역 : HTML. CSS와 같은 정적 리소스가 사용되는 영역
- WEB-INF : 자바 클래스와 라이브러리, 그리고 설정 정보가 들어가는 곳
참고 링크
- Spring Web, Thymeleaf 2개만 선택해주었다.
- Spring Web : Spring으로 Web을 만들기 위해 반드시 필요한 종속성, RESTful한 API를 만드는 기능, Spring MVC를 만드는 기능, Apache Tomcat 내장 서버 등이 포함
- Thymeleaf : 백엔드 개발에 사용되진 않지만, 테스트용 프론트엔드를 간단하게 만들고 싶을 때 사용
프로젝트 구조
- 프로젝트를 생성하면 아래와 같은 파일들이 자동으로 생성된다. (왼쪽 폴더 구조)
- build.gradle이 빌드가 되어야 위와 같은 폴더 구조로 된다. (패키지 적용, gradle 폴더 생성 … 등등)
원격 저장소 연결 및 main 브랜치로 이동 (추가한 부분)
github에 공부 기록을 남길 것이기 때문에, 원격 저장소 연결 및 main 브랜치를 생성해주었다.
샘플 코드 작성
- 프로젝트 디렉토리에서 다음과 같은 하위 디렉토리 구조를 생성
- hello라는 프로젝트라고 가정한다면, 아래와 같다.
└── src
└── main
└── java
└── hello
- 예시로, Greeter와 DemoApplication을 작성했다.
Greeter
package hello;
public class Greeter { // class 선언
public String sayHello() { // 내부 함수
return "Hello world!";
}
}
DemoApplication
package hello;
public class DemoApplication {
public static void main(String[] args) {
Greeter greeter = new Greeter(); // 생성자 호출
System.out.println(greeter.sayHello()); // 생성자 내부 함수 호출
}
}
빌드
빌드 : 빌드란 소스 코드 파일을 실행할 수 있는 소프트웨어로 변환하는 과정이다.
- 프로젝트 디렉토리에서 ./gradlew build 를 실행하면, build.gradle 파일에 정의한 내용을 기준으로 빌드가 된다.
- 빌드 결과는 아래와 같은 형태로 생성된다. (com.spring.study 패키지가 없을 때)
build
├── classes
│ └── main
│ └── hello
│ ├── Greeter.class
│ └── DemoApplication.class
├── dependency-cache
├── libs
│ └── gs-gradle-0.1.0.jar
└── tmp
└── jar
└── MANIFEST.MF
- gradlew 파일은 Gradle Wrapper로서 Gradle을 각 개발자나 CI 서버에 깔지 않고, 프로젝트에 함께 포함시켜 배포할 수 있는 방법을 제공
- Gradle Wrapper을 사용하는 이유는 환경에 종속되지 않고 프로젝트를 빌드할 수 있게 하기 위함
- build.gradle은 Gradle의 빌드 스크립트로서 빌드 시 필요한 작업을 정의하거나 의존성을 관리
의존성 선언
- 대부분의 응용 프로그램은 공통 또는 복잡한 기능을 처리하기 위해 외부 라이브러리를 활용
코드 수정하기 (요구 사항)
- “Hello world!” 출력 시 현재 날짜와 시간을 출력하도록 수정
- 기본 Java 라이브러리의 날짜 및 시간 기능(import java.time.LocalDateTime;) 대신 Joda Time 라이브러리를 사용하도록 한다.
- Joda Time의 LocalTime 클래스를 사용하여 아래와 같이 현재 시간을 가져와서 출력하기
package hello;
import org.joda.time.LocalTime;
public class DemoApplication {
public static void main(String[] args) {
LocalTime currentTime = new LocalTime();
System.out.println("The current local time is: " + currentTime);
Greeter greeter = new Greeter();
System.out.println(greeter.sayHello());
}
}
[build.gradle에 의존성 추가하기]
implementation "joda-time:joda-time:2.2"
+) build.gradle 뜯어보기
- 현재 build.gradle 파일
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.spring'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation "joda-time:joda-time:2.2"
}
tasks.named('test') {
useJUnitPlatform()
}
mavenCentral 오픈 소스 라이브러리를 호스팅하는 저장소 추가
repositories {
mavenCentral()
}
jdk 선언
java {
sourceCompatibility = '17'
}
의존성 추가
- dependencies 블록을 사용하여 Joda Time에 대한 의존성을 선언
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation "joda-time:joda-time:2.2"
}
스프링 애플리케이션 실행하기
- SpringBootApplication 코드를 추가하고 실행하면, 현재 시간과 Hello World가 출력되고 springboot가 실행된다.
BDD 동아리 Spring 스터디 공부 자료를 참고하였습니다.
우테코의 일부 코치님들이 진행하는 프로젝트에서 지원해주셨습니다.
'💻 개발 > Spring' 카테고리의 다른 글
HTTP - Spring MVC (0) | 2023.12.04 |
---|---|
API Web Application 만들기 - Spring MVC (0) | 2023.12.04 |
Framework와 Project (0) | 2023.11.29 |
Repository Interface 메소드 실습 (1) (0) | 2023.07.20 |
Repository Interface 계층 살펴보기 (0) | 2023.07.20 |