자바/이론 공부

[JAVA / Spring] Maven에 대하여

2가 2023. 2. 22. 20:26

공부하게 된 계기

 - 나는 spring 개인 프로젝트를  maven을 사용하지 않고 작업중이었는데 (사실 잘 몰라서 안사용했었음) spring에 대해 찾아볼때마다 spring의 짝꿍인듯 함께 maven얘기(혹은 gradle)를 하는 것이다. 거기다 개인프로젝트 중 spring 구조에 대한 지식이 부족함을 느껴 spring 책을 함께 공부하고 있는데 거기도 maven을 기본으로 사용하길래 도대체 어떤것인가 궁금증이 들어 찾아보게되었다.

 

 

Maven / Gradle 이란?

 - 빌드 관리 툴

 - 프로젝트에서 필요한 xml, properties, jar 파일들을 자동으로 인식하여 빌드해주는 도구이다. (대표적으로 pom.xml)

 - 소스코드를 컴파일, 테스트, 정적분석 등을 하여 실행가능한 앱으로 빌드.(라이프 사이클?)

 - 프로젝트 정보 관리, 테스트 빌드, 배포 등의 작업을 간편하게 진행해준다.

 - 외부 라이브러리를 참조하여 자동으로 다운로드 및 업데이트를 해준다. (원래는 라이브러리를 하나씩 다운로드해서 수작업으로 넣어줌!)

 

 

* Spring STS를 이용하는 방법이 두가지가 있다!

 1. maven 빌드를 사용

    - 프레임워크에 필요하거나 프로젝트 진행에 있어서 필요한 라이브러리들을 쉽고 간편하게 관리

 

 2. maven을 사용하지 않는 경우 (내가 지금 bookAe 프로젝트에 사용하는 방법)

    - 내가 직접 관련 라이브러리 파일을 모두 내려받아서 추가

 

 

Maven?

 - Ant 대체. (Ant는 요즘 사용하지않음. 완전 옛날꺼임)

 - 프로젝트 빌드와 라이프사이클, 사이트 생성 등 프로젝트 전반을 위한 관리도구이다.

 - pom.xml을 가지고 라이브러리관리 (다운받은 파일을 사용하는게 아니라서 변동사항(라이브러리 내용 수정이나 업데이트같은)이 생겨도 알아서 업데이트해줌)

 - 라이프사이클이 있다. (빌드순서 정리, 깔끔하게 정리 가능하게 해줌)

 

 

Gradle? (아직 잘 모르겠다. gradle에 대해서는...)

 - 안드로이드 프로젝트의 표준 빌드 시스템

 - 멀티 프로젝트의 빌드에 최적화 (대규모 프로젝트에서 성능 good!)

 - Maven에 비해 더 빠른 처리속도와 더 간결한 구성 (xml이 아니라 Groovy 스크립트를 활용하기 때문)

 

 

+) 요즘은 gradle이 유행이라고 함! 하지만 gradle과 maven 둘 중 하나를 이해하고 있으면 나머지를 배우는건 쉽다고 한다.

 

 

*maven의 프로젝트 폴더와 pom.xml은 직접 생성해도 되지만 메이븐이 제공하는 아키타입을 사용하여 생성할 수도 있다.

 

 

*Maven 기본 디렉토리 구조

server연동을 안해줘서 에러가 생겼다. 에러는 무시!

 - src/main/java : 자바 소스파일이 위치한다.

 - src/main/resources : properties나 xml등 리소스 파일이 위치한다. 클래스패스에 포함된다. (여기서 말하는 classpath라는게 어떤건지 잘 모르겠다.)

 - src/main/webapp : 웹 어플리케이션 관련 파일이 위치한다.(WEB-INF폴더나 JSP파일 등)

 - src/test/java : 테스트 자바 소스 파일이 위치한다.

 - src/test/resources : 테스트과정에서 사용되는 리소스 파일이 위치한다. 테스트에 사용되는 클래스패스에 포함된다.

 

 

*maven 과정 : 모든 코드를 컴파일하고 테스트한 후에 프로젝트를 패키징하여 배포가능한 jar파일로 만든다.

 

 

*maven의 pom.xml

 - Project Object Model 정보를 담고 있는 파일이다.

 

 - pom.xml의 주요 설정 정보

    - 프로젝트 정보 : 프로젝트의 이름, 개발자 목록, 라이센스 등의 정보

    - 빌드 설정 : 소스, 리소스, 라이프 사이클별 실행할 플로그인 등 빌드와 관련된 설정

    - 빌드 환경 : 사용자 환경별로 달라질 수 있는 프로파일 정보

    - POM 연관 정보 : 의존 프로젝트(모듈)(pom.xml에 <dependency>태그안에 넣는 프로젝트들을 말함.), 상위 프로젝트, 포함하고 있는 하위 모듈 등 (프로젝트도 자바의 상속마냥 상위와 하위가 있다는 건가...?)

 

+)pom 프로젝트 관련 태그

    - <groupId> : 프로젝트의 그룹 ID 설정. 프로젝트가 속하는 그룹 식별자, 회사, 본부, 단체를 의미하는 값. ex) com.naver라던가 com.sujin같은..

    - <artifactId> : 프로젝트의 Artifact ID 설정. 프로젝트 결과물의 식별자. 프로젝트나 모듈을 의미하는 값. ex)bookAe같은 프로젝트 이름? 을 말하는 것같다.

    - <version> : 버전 설정

    - <packaging> : 패키징 타입 설정. jar 나 war 같은.

    - <dependencies> : 이 프로젝트에서 의존하는 다른 프로젝트 정보를 기술. (의존 프로젝트! 모듈!)

        === <dependencies>안에 있는 태그들 ===

        - <dependency> : 의존하는 프로젝트 POM 정보를 기술

        - <groupId> : 의존하는 프로젝트의 그룹 ID

        - <artifactId> : 의존하는 프로젝트의 artifact ID

        - <version> : 의존하는 프로젝트의 버전

        - <scope> : 의존하는 범위를 설정 (이 태그를 사용하지 않을 때도 있음.)

 

 

*dependency 설정

 - maven의 가장 큰 장점!

    - 메이븐을 사용하지 않을 경우에는 코드에 필요한 라이브러리와 그 라이브러리가 필요로 하는 다른 라이브러리들까지 직접 찾아 설치해 줘야 한다.

    - 메이븐을 사용하면 dependency 설정만 해주면 관련 라이브러리까지 메이븐이 알아서 다운로드 받아준다.

 

    +) 메이븐이 모듈하나를 dependency 설정했을 때 일어나는 일

        - 모듈의 관련 POM 파일을 다운받는다. -> POM파일에 명시한 의존 모듈을 함께 다운받는다. -> 다운로드 받은 모듈이 필요로 하는 모듈들을 다 다운받게된다.

 

+)나는 학원에서 강사님이 lib에 들어갈 라이브러리들을 전부 다운받아주셨기때문에 메이븐없이 하는 작업의 불편함을 못느꼈었나보다. 내가 하나하나 일일이 찾아 다운받을 생각을 하니까 어질어질해진다. maven 최고네....

 

 - <scope>가 포함된 경우와 안포함된 경우

    - <scope>는 의존하는 모듈이 언제 사용되는지를 설정한다.

 

   === <scope>에 오는 값 ===

     - compile : <scope>설정을 하지 않을 경우 기본값이다. 컴파일할 때 필요. 테스트 및 런타임에도 클래스패스에 포함된다.

     - runtime : 런타임에 필요.  코드를 컴파일 할 때는 필요하지 않지만 실행할 때 필요하다면 runtime. 배포시 포함. ex) JDBC드라이버

     - provided : 컴파일 할 때 필요하지만 실제 런타임때에는 컨테이너 같은 것에서 기본으로 제공되는 모듈임을 의미. 배포시 제외. ex) 서블릿이나 JSP API. (스프링 컨테이너는 스프링에서 자바 객체들을 관리하는 공간, 서블릿 컨테이너는 서블릿을 관리하는 톰캣같은 것. 이라는데 "컨테이너 같은 것에서 기본으로 제공되는 모듈" 이게 도대체 무슨 소릴까? 런타임때에는 '관리하는 곳'에서 서블릿이나 jsp같은게 기본으로 제공된다는 걸까??)

     - test : 테스트 코드를 컴파일 할 때 필요. 테스트 시에 클래스패스에 포함되지만 배포시에는 제외.

 

 

*메이븐의 원격 리포지토리와 로컬 리포지토리

 - 메이븐은 프로젝트에 필요한 플러그인이나 dependency에 설정한 모듈을 메이븐 중앙 리포지토리에서 다운받는다.

 - 원격 리포지토리에서 다운받은 모듈은 로컬 리포지토리에 저장된다.

 - 로컬 리포지토리에 저장 후에는 계속 로컬 리포지토리에 저장된 파일을 사용한다.

 

 

*메이븐의 라이프사이클 LifeCycle

 - 메이븐은 프로젝트의 빌드 라이프사이클을 제공한다.

 - 앞에서 말했던 compile, test, package하는 작업이 모두 빌드 라이프사이클에 속하는 단계이다.

 - 크게 clean, build(default), site 세 가지의 라이프사이클을 제공한다.

 - 각 라이프사이클은 순서를 갖는 단계(phase)로 구성된다. 각 단계별로 실행할 플러그인(plugin) 골(goal)이 정의되어 있어 각 단계마다 알맞은 작업을 실행한다.

 - 라이프사이클의 특정 단계를 실행하면 그 단계의 앞에 위치한 모든 단계를 실행한다. + 각 단계에 묶인 골을 실행한다. ( 플러그인 골)

 

+)플러그인 골 plugin goal

    - 메이븐에서 플러그인을 실행할 때에는 '플러그인이름:플러그인지원골' (플러그인 : 골) 형식으로 실행할 기능을 선택한다.

 

단계 설명 단계에 묶인 플러그인 실행(goal)
generate-sources 컴파일 과정에 포함될 소스를 생성한다. 예를 들어 DB 테이블과 매핑되는 자바 코드를 생성하는 작업을 이 단계에서 실행한다.  
process-sources 필터와 같은 작업을 소스 코드에 처리한다.  
generate-resources 패키지에 포함할 자원을 생성한다.  
process-resources 필터와 같은 작업을 자원 파일에 처리하고, 자원 파일을 클래스 출력폴더에 복사한다. resources:resources
compile 소스 코드를 컴파일해서 클래스 출력 폴더에 클래스를 생성한다. compiler:compile
generate-test-sources 테스트 소스 코드를 생성한다. 예를들어 특정 클래스에서 자동으로 테스트 케이스를 만드는 작업을 이 단계에서 실행한다.  
process-test-sources 필터와 같은 작업을 테스트 소스 코드에 처리한다. resources:testResources
generate-test-resources 테스트를 위한 자원 파일을 생성한다.  
process-test-recources 필터와 같은 작업을 테스트 자원 파일에 처리하고, 테스트 자원 파일을 테스트 클래스 출력 폴더에 복사한다.  
test-compile 테스트 소스 코드를 컴파일해서 테스트 클래스 출력 폴더에 클래스를 생성한다. compiler:testCompile
test 테스트를 실행한다. surefile:test
package 컴파일 한 코드와 자원 파일들을 자원 파일들을 jar, war와 같은 배포 형식으로 패키징한다. jar:jar
or
war:war
install 로컬 리포지토리에 패키지를 복사한다. install:install
deploy 생성한 패키지 파일을 원격 리포지토리에 등록하여, 다른 프로젝트에서 사용할 수 있도록 한다. deploy:deploy

 - 순서대로 메이븐의 전체적인 흐름이다.

 - 소스 생성 > 소스코드에 필터 처리 > 자원 생성 > 자원파일에 필터 처리 > 소스코드를 컴파일 >

   테스트 소스 코드 생성 > 테스트 소스 코드에 필터 처리 > 테스트 자원파일 생성 > 테스트 자원 파일에 필터 처리 > 테스트 소스 코드 컴파일 > 테스트 실행 > 

   컴파일한 코드와 자원 파일들을 배포 형식으로 패키징(파일 만들기) > 로컬에 패키지 복사 > 원격에 패키지 등록

 

 

 

 

 

 

**내가 배우고 이해한 내용을 기억해놓기 위해 적어놓은 것이니 정확한 정보가 아닐 수도 있음.

참고

 - 초보 웹 개발자를 위한 스프링5 프로그래밍 입문

 - https://youtu.be/3Jp9kGDb01g