검색

레이블이 Lombok인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Lombok인 게시물을 표시합니다. 모든 게시물 표시

2023년 3월 22일

코딩 - Serverless 을 위한 Spring Boot 기반 응용프로그램 개발하기 : Part 2

다중모듈 프로젝트 구성

먼저 모듈의 의미를 정의해보면, 모듈이란 ...
  • 다른 모듈의 코드와 분리된 코드베이스를 갖는다.
  • 빌드 결과물은 개별 아티팩트(JAR 파일)로 변환된다.
  • 다른 모듈이나 외부 라이브러리에 대한 의존성을 정의할 수 있다.
다중모듈 프로젝트는 여러 모듈로 구성된 프로젝트로, 각 모듈은 애플리케이션의 개별적인 기능 또는 구성 요소를 의미한다. 다음은 Spring Boot 멀티모듈 프로젝트를 사용할 때의 몇 가지 장점과 단점이다. 

■ 장점
  1. 모듈식 구조: 멀티모듈 프로젝트를 사용하면 우려 사항을 명확하게 분리할 수 있으며 모듈식 구조로 애플리케이션을 유지 관리하고 확장하기가 더 쉬워진다. 
  2. 개선된 구조: 멀티모듈 프로젝트는 코드들이 기능별로 단일 모듈에 그룹화되어 있어 개발자가 코드를 더 쉽게 찾고 수정할 수 있다.
  3. 재사용 가능성: 멀티모듈 프로젝트의 모듈은 다른 프로젝트에서 재 사용할 수 있으므로 새 애플리케이션을 개발할 때 시간과 노력을 절약할 수 있다.
  4. 명확한 종속성: 멀티모듈 프로젝트를 사용하면 모듈 간의 종속성을 명확하게 정의할 수 있으므로 복잡성을 관리하고 애플리케이션의 구조가 잘 잡혀 있는지 확인할 수 있다.

■ 단점
  1. 복잡성 증가: 멀티모듈 프로젝트는 단일 모듈 프로젝트보다 더 복잡할 수 있으므로 이해하고 유지 관리하기가 더 어려울 수 있다. 프로젝트에 많은 모듈이 있는 경우 특히 그렇다.
  2. 빌드 시간 증가: 멀티모듈 프로젝트는 각 모듈을 개별적으로 빌드해야 하므로 단일 모듈 프로젝트보다 빌드 시간이 더 오래 걸릴 수 있다. Gradle 또는 Maven을 사용하여 빌드 프로세스를 관리하면 이 문제를 완화할 수 있다.
  3. 설정 시간 증가: 다중모듈 프로젝트를 설정하는 데는 관리해야 할 구성 파일과 빌드 스크립트가 더 많기 때문에 단일 모듈 프로젝트를 설정하는 것보다 시간이 더 오래 걸릴 수 있다.
  4. 순환 종속성 위험: 멀티모듈 프로젝트에서는 모듈 간에 순환 종속성이 발생할 위험이 있으며, 이로 인해 런타임 오류 및 성능 저하와 같은 문제가 발생할 수 있다. 이 문제를 방지하려면 모듈 간의 종속성에 세심한 주의를 기울여야 한다.

요약하면 Spring Boot 멀티모듈 프로젝트는 모듈성, 재사용성, 명확한 종속성 등 여러 가지 이점을 제공할 수 있지만 복잡성이 증가하고 빌드 시간이 길어질 수 있다는 단점도 있다. 

멀티모듈 프로젝트를 구현하기로 결정한 것은 프로젝트 구성을 복잡성을 고려하더라도 명확한 모듈화를 위함이다. 아래 프로젝트는 3개의 멀티모듈로 구성되어 있다. 



각 모듈은 Java 소스, build.gradle 파일로 구성된 별도의 폴더에 위치한다. 

  1. 최상위 build.gradle 파일은 모든 하위 모듈 간에 공유되는 빌드 동작을 구성하여 하위 모듈에서 중복할 필요가 없도록 한다.
  2. studio 모듈에는 실제 Spring Boot 애플리케이션과 컨텍스트 구성을 위한 JavaConfig 이 포함되어 있다. 
  3. architecture-ee 모듈은 JDBC 프로그램밍 및 공통에 해당하는 클래스와 스프링 컨텍스트 구성을 돕는 JavaConfig 클래스를 포함하고 있다. 
  4. architecture-community 웹 모듈은 애플리케이션의 서비스 와 웹 계층을 구현한다. 

부모빌드 파일

① 최상위에 위치한 부모빌드에 자식에 해당하는 모듈을 포함 하려면 부모 settings.gradle 파일에  include  키워드를 사용하여 모듈들을 추가한다. 

rootProject.name = 'studio-server'
include "architecture-ee"
include "architecture-community"
include "studio"

이제 상위 폴더에서 ./gradlew 빌드를 실행하면 Gradle 은 자동으로 모듈 간 종속성을 해결하고 settings.gradle 에 나열된 순서와 관계없이 (모듈간의 의존성을 파악하여) 올바른 순서로 빌드를 수행한다. 

예를 들어, 공통에 해당하는 architecture-ee  모듈은 다른 모든 모듈이 종속되어 있으므로 다른 모든 모듈보다 먼저 빌드된다.

부모 build.gradle 파일에서 모든 하위 모듈에서 공유되는 기본 구성을 정의한다: 이를 통하여 하위 모듈의 설정을 단순화할 수 있다.

데이터베이스 마이그레이션 : Flyway

Flyway 는 데이터베이스 스키마 변경을 관리하기 위해 Spring Boot와 함께 사용할 수 있는 인기 있는 데이터베이스 마이그레이션 도구이다. 다음은 Spring Boot에서 Flyway를 사용할 때의 몇 가지 장점과 단점이다.

■ 장점
  1. 손쉬운 통합: Flyway는 간단한 구성을 통해 Spring Boot 애플리케이션에 쉽게 통합할 수 있다.
  2. 버전 관리: Flyway를 사용하면 데이터베이스 스키마 변경 사항을 형상관리와 유시한 버전 제어 방식으로 관리할 수 있으므로 시간 경과에 따른 변경 사항을 쉽게 추적하고 관리할 수 있다.
  3. 일관된 데이터베이스 상태: Flyway는 프로젝트에 참여하는 개발자 수나 데이터베이스가 배포된 환경에 관계없이 데이터베이스의 모든 인스턴스가 동일한 상태를 유지하도록 돕는다.
  4. 반복 가능한 마이그레이션: Flyway는 반복 가능한 마이그레이션을 지원하므로 새 열 또는 인덱스 추가와 같은 작업에 사용할 수 있으며, 이러한 변경 사항이 데이터베이스의 모든 인스턴스에 일관되게 적용되도록 보장한다.
  5. 여러 데이터베이스를 지원: Flyway는 Oracle, MySQL, PostgreSQL, SQL Server 등 다양한 데이터베이스를 지원하므로 데이터베이스 스키마 변경을 관리할 수 있는 다목적 솔루션이다.

■ 단점
  1. 추가 구성: Flyway를 Spring Boot 애플리케이션에 통합하려면 몇 가지 추가 구성이 필요하므로 애플리케이션이 더 복잡해질 수 있다.
  2. 학습: Spring Boot와 함께 Flyway를 사용하려면 새로운 명령과 규칙을 배워야 하므로 일부 개발자에게는 새로운 기술에 대한 학습이 필요하다.
  3. 기존 스키마와 충돌: Flyway에서 관리하지 않는 기존 스키마 변경 사항이 있는 경우 충돌 및 잠재적인 데이터 손실의 위험이 있다.
  4. 제한된 롤백 지원: Flyway는 마이그레이션 실패를 감지하고 오류 메시지를 제공할 수 있지만, 마이그레이션의 자동 롤백 기능은 제공하지 않으므로 수동 개입이 필요할 수 있다.

요약하면, Spring Boot와 함께 Flyway를 사용하면 손쉬운 통합, 버전 제어, 일관성, 반복 가능한 마이그레이션, 여러 데이터베이스 지원 등 여러 가지 이점을 얻을 수 있다. 하지만 추가 구성, 학습, 기존 스키마와의 충돌, 제한된 롤백 지원 등 몇 가지 잠재적인 단점도 있다. 

초기 개발 및 배포시 Flyway 가 제공하는 데이터베이스 마이그레이션 간소화 기능을 사용하여 실행과 동시에 필요한 테이블들과 기초 데이터들에 대한 마이그레이션을 자동화는 제한된 목적이라면 좋은 선택일 것 같다.

Flyway에서 마이그레이션 SQL 파일은 반드시 다음 이름 패턴을 준수해야한다: ( ➜ 공식 문서)

  • Part 1:  "V" 는 버전 "U" 는 실행취소 마지막으로 "R" 은 반복 작업을 의미하며 스프립트 파일 언제나 이 문자로 시작해야 한다. 이들 시작 문자는 변경할 수 있다. 
  • Part 2:  R (반복작업) 을 제외하고 점 또는 밑줄로 버전을 원하는 만큼 구분하여 사용할 수 있다. (예: 0, 1, 001,  1.2.3, 2021.09.24.12.55.32, ...)
  • Part 3: "__" (밑줄 2개) 버전 파트와 설명 파트를 구분한다. 구분자는 변경할 수 있다.
  • Part 4: 작업 설명으로 밑줄 또는 공백으로 단어를 구분할 수 있다. 
  • Part 5:  스크립트 확장자을 의미하며 변경이 할 수 있다.

 Spring Boot 에서 Part 1 ~ Part 5 항목은 application.properties (또는 application.yml)  에 설정을 통하여 변경할 수 있다. ➜ 공식문서

Flyway 는 아래와 같이 의존성을 build.gradle 에 추가하는 작업으로 시작한다. (MySql 을 사용한다면 flyway-mysql 의존성 추가 필요)

dependencies {
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-mysql'

}

데이터베이스 마이그레이션 SQL 파일 명명 규칙 중에서 변경 가능한 것들은  application.properties (또는 application.yml) 속성을 사용하여 필요에 맞게 조정한다. 


위 설정의 경우 jar 파일에서 schema/mysql 스클립트 파일을 검색하여 마이그레이션을 실행하고 파일 이력 관리를 위하여 "flyway_schema_history" 테이블을 생성하여 관리하게 된다.



보안 : Spring Security

Spring Security 5.7.0-M2  버전 부터는 사용자의 컴포넌트 기반의 보안 설정 권장을 목적으로 WebSecurityConfigurerAdapter 을 더이상 사용하지 않는다.  ➜ 스프링 공식 블로그

WebSecurityConfigurerAdapter 를 상속받고 configure 메서드를 오버라이딩하여 설정들을 정의하는 방법이 아닌 설정들을 하나의 객체로 정의하고 SecurityFilterChain 을 리턴하는 스프링에서 새롭게 권장하는 새로운 방법을 사용했다. 기존에 사용하던 XML 방식 정의를 Java 형식으로 변환을 하여 사용하였는데 xml 과 대응하는 방법들이 제공되어 어렵지 않게 설정할 수 있었다.



템블릿엔진 : Freemarker

Thymeleaf, FreeMarker, Velocity 와 같은 템플릿 엔진은 일반적으로 HTML 페이지의 서버 측 렌더링을 위해 Spring Boot 애플리케이션에서 사용된다. 

다음과 같은 경우라면 은 Spring Boot 애플리케이션에서 템플릿 엔진 사용을 고려할 충분한 이유가 된다. 

  1. 서버 측 렌더링: 템플릿 엔진을 사용하면 서버 측에서 HTML을 렌더링할 수 있으므로 SEO, 접근성 및 성능을 개선할 수 있다.
  2. 재사용 가능성: 템플릿은 웹사이트의 여러 페이지 또는 섹션에서 재사용할 수 있으므로 코드 중복을 줄일 수 있다.
  3. 유지 보수성: 템플릿 엔진을 사용하면 프레젠테이션 로직과 비즈니스 로직을 분리할 수 있어 코드 유지 관리 및 수정이 용의하다.
  4. Spring Boot와의 손쉬운 통합: 많은 템플릿 엔진이 Spring Boot와 통합되어 있어 Spring Boot 애플리케이션에서 쉽게 사용할 수 있다.

반면 애플리케이션이 HTML 페이지의 서버 측 렌더링이 필요하지 않거나 프런트엔드 구축에 React 또는 Angular와 같은 클라이언트 측 프레임워크를 사용하는 것을 선호하는 경우 템플릿 엔진을 사용할 필요가 없을 수 있다.

freemarker 템플릿 엔진은  Spring Boot application properties (application.yml) 에 정의하거나  커스텀이 필요한 경우 WebMvcConfigurer 을 직접 구현하여 정의 하는 방법으로 사용한다.  


https://docs.spring.io/spring-boot/docs/2.7.9/reference/html/application-properties.html

코딩 - Serverless 을 위한 Spring Boot 기반 응용프로그램 개발하기 : Part 1

◼︎ 환경 

  • Model : MacBook Pro (14-inch, 2021)
  • CPU : Apple M1 Pro
  • MENORY : 16GB
  • DISK : 512 GB SSD
  • OS : macOS 13.2.1 (22D68)
  • TOOLS : Visual Studio Code


왜 Spring Boot 인가 ?

Spring Boot 는 개발자에게 여러 가지 이점을 제공하는 강력한  프레임워크이다. 아래는 몇 가지 주요 이점이다.

  1. 더 빠른 개발: Spring Boot는 애플리케이션을 빠르고 쉽게 빌드하고 배포할 수 있는 방법을 제공. 사전 구성된 템플릿 세트와 다양한 라이브러리가 있어 개발 속도 향상.
  2. 간소화된 구성: Spring Boot는 작성해야 하는 상용구 코드의 양을 줄여주는 간소화된 구성 메커니즘을 제공.
  3. 자동 구성: Spring Boot의 자동 구성 기능은 프로젝트에 추가된 종속성을 기반으로 애플리케이션을 자동으로 구성. 수동 구성이 필요하지 않으므로 오류 발생 가능성이 줄어들고 시간이 절약.
  4. 프로덕션 준비 완료: Spring Boot 는 상태 확인, 메트릭 및 모니터링과 같이 애플리케이션을 프로덕션에 바로 사용할 수 있도록 하는 데 필요한 기능을 제공.
  5. 임베드 가능한 서버: Spring Boot 는 별도의 서버에 애플리케이션을 배포할 필요가 없는 임베디드 서버를 포함되어 배포가 더 쉽고 빠릅니다.
  6. 다른 Spring 프로젝트와의 손쉬운 통합: Spring Boot는 Spring Data 및 Spring Security와 같은 다른 Spring 프로젝트와 원활하게 통합되므로 복잡한 애플리케이션을 더 쉽게 빌드할 수 있음.
  7. 대규모 커뮤니티 지원: Spring Boot 는  대규모 개발자 커뮤니티 보유. 이를 통해 프레임워크가 지속적으로 개선되고 발전.

전반적으로 Spring Boot는 여러 가지 장점을 제공하는 강력한 프레임워크로서 현대적이고 확장 가능하며 강력한 애플리케이션을 구축하는 데 이상적인 선택이 될 수 있다. 

이미 Spring 을 사용하는 경우 Spring Boot 로 변경할 이유가 있을까?
Spring 을 기반으로하는 애플리케이션을 더 간단하고 빠르게 개발하고 배포할 수 있는 방법을 찾고 있다면 Spring Boot가 좋은 선택이 될 수 있다.  그러나 이미 구성 프로세스에 익숙하고 Spring Boot 가 제공하는 추가 기능이 필요하지 않다면 전환할 필요가 없을 수도 있다.

개발 도구 준비하기 

Visual Studio Code 환경에서 Spring Boot 개발을 위해 ⑴ VS Code 를 설치하고 ⑵ Spring Boot Extension Pack 확장팩을 설치한다.
 

Install the Spring Boot Extension Pack




어떤 버전의 Spring Boot 를 사용할 것인가 ?

Spring Boot 는 버전에 따라 호환되는 자바 버전에 차이가 있다. 이런 이유에서 사용(희망)하는 자바 버전을 고려하여 Spring Boot 버전을 선택해야한다.

2022 자바 생태계 현황 보고서 (https://newrelic.com/resources/report/2022-state-of-java-ecosystem)에 따르면 현재 48% 이상의 애플리케이션이 프로덕션 환경에서 Java 11을 사용하고 있으며(2020년 11.11%에서 증가), Java 8이 근소한 차이로 2위를 차지하며 46.45%의 애플리케이션이 프로덕션 환경에서 이 버전을 사용하고 있다.


운영 환경의 LTS 버전과 비교했을 때 비-LTS Java 버전에 대한 사용률은 극히 낮았으며, 비-LTS Java 버전을 사용하는 애플리케이션의 비율은 2.7%에 불과했다. 


최신 Spring Boot 버전은 3.x 이며 (https://www.marcobehler.com/guides/spring-and-spring-boot-versions) 최소 17 이상의 자바 버전을 요구하고 있다.  참여 프로젝트에서 주로 Spring 5.x 를 사용하고 있었고 운영 배포를 고려하여 가장 많이 사용하고 있는 자바 11 버전을 지원하는 Spring Boot  는 2.x  버전을 선택했다.


Spring Boot 프로젝트 만들기

요즘 개발 도구는 VS Code 를 주력으로 사용하고 있어 고민없이 VS Code 에서 새로운 Spring Boot 프로젝트 생성하는 것만 고려했다. VS Code 에서 Spring Boot 프로젝트 생성은 ① Control + Shift + P 키를 입력하여 명령 팔레트 창을 실행 Spring Initializer 을 선택하여 프로젝트를 생성한다. 또는 ② EXPLORER 에서 Create Java Project 버튼을 클릭하고 Spring Boot 을 선택한다. (참고: https://spring.io/quickstart )

① Control + Shift + P > pring Initializer : Create a Gradle Project .. 선택

 EXPLORER 에서 Create Java Project 버튼을 클릭하여 프로젝트 생성
 




Spring Boot 프로젝트 생성은 아래와 같은 옵션을 선택했다.  지금까지 자바 프로젝트는 Maven 을 사용했었는데 이번에는 Gradle 을 선택했다. 

  • Project : Gradle - Groovy
  • Language : Java
  • Spring Boot : 2.7.9
  • Packaging : Jar
  • Java : 11

프로젝트 생성시에 스타터(Starters) 의존성을 세팅하는 과정이 있는데 Spring Boot 의 우수성 중 하나가 스타터을 기반으로하는 편리한 의존성에 관리에 있는것 같다.  기존 Spring 개발 환경에서는 많은 시간을 투자하여 의존성을 관리해야 했었는데, 이러한 문제를 해결하기 위하여 도입된 Spring Boot 스타터는  약 50개 이상의 다양한 사전에 정의된 스타터들이 제공되고 있다.  (참고 : Starters) Starter 사용의 장점은 아래와 같다. 

  1. 개발자의 의존성 구성 시간이 줄어들어 생산성이 향상
  2. 추가해야 할 종속성 수가 줄어들기 때문에 POM 관리가 더 쉬워짐.
  3. 테스트를 거쳐 프로덕션에 사용할 수 있고 지원되는 종속성 구성.
  4. 종속 요소의 이름과 버전을 기억할 필요가 없음.

스타터는 아래와 같이 dependecies 항목에 추가하여 사용할 수 있다. 단지 이것으로 필요한 관련 된 모든 라이브러리들의 의존성이 해결된다. 
 
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'


DataSource 추가하기 

데이터접속을 위한 DataSource 설정이 조금 다른 부분이 있는데 기존 Spring 방식을 사용할 수도 있고 Spring Boot 에 제공하는 기본 설정을 사용할 수 도 있다. 가능한 Spring Boot 의 기능을 최대한 사용하려는 목적이 있어 Spring Boot 의 기본 설정(application.properties)을 사용하여 설정하였다. 설정은 가독성을 고려하여 추가설정없이 지원되는 yml 형식을 사용하였다. 리소스 위치는 config 폴더 이하에 저장하여 사용하였다. ( 기본적으로 Spring Boot 는 자동으로 기본 설정 파일을 로드하는 규칙이 있는데 리소스의 루트 또는 config 폴더를 검색하여 로드하도록 되어있다.)
 
Spring Boot 는 다양한 Connection Pool 기술은 제공하고 있는데 HikariCP 을 권장하고 있다.  HikariCP 성능 팁 설정(MySQL) 을 참고하여 다음과 같이 설정하였다. (설정을 위한 예시가 없어 조금 시간이 소요되었다.) 

➜ 편리하게도 spring-boot-starter-jdbc 또는 spring-boot-starter-data-jpa “starters” 추가하면 HikariCP 의존성도 자동으로 추가된다. *-data-jpa starter 를 사용하면 디폴트로 Hibernate  기반 JPA 을 사용할 수 있도록 관련 빈들이 자동으로 구성 및 생성된다.


JDBC Programming

Spring Boot JDBC는 (*-data-jdbc starter 을 사용한 경우) 시작 중에 DataSource, JdbcTemplate 및 NamedParameterJdbcTemplate와 같은 데이터베이스 관련 빈이 구성 및 생성되며, 이를 사용하려면 원하는 빈을 @Autowired 하고 사용하면 된다. ( 코드 참고 : https://mkyong.com/spring-boot/spring-boot-jdbc-examples/) 



Logging

Spring Boot는  로깅을 구현하는 log4j, logback 등과 같은 로깅 프레임워크에 대한 추상화 기능 제공을 위하여 SLF4J (Simple Logging Facade for Java) 를 사용하고 있다. Lombok (어노테이션 기반의 유틸리티 라이브러리) 을 사용하면 좀더 간단하게 @Slf4j을 클래스 상단에 정의하는 것 만으로 바로 로깅 기능을 할 수 있다.


다음은 SLF4J 기반의 로깅 예이다. Lombok 을 사용하는 경우 Logger 선언 없이 @Slf4j 어노테이션만 선언하여 바로 log 변수로 사용할 수 있다.


Lombok 는 dependecies 항목에 아래와 같이 추가하여 이용한다. 로깅 이외에도 다양한 어노테이션들을 제공하고 있고 잘 사용하면 코딩 더욱 쉬워질 수 있다.

dependencies {
implementation 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}