소스코드에서 배포가능한 아티팩트를 빌드하는데 사용되는 빌드도구
사전적의미로
특별한 지정이없으면 /src/main/java에 소스코드가 있고
리소스는 /src/main/resources 에있다고 가정하며,
테스트는 /src/test 에있다고 가정하고 프로젝트는 JAR파일을 생성한다고 가정한다.
메이븐은 바이트코드를 /target/classes로 컴파일한다음 배포가능한 JAR을 /target 으로 생성하기를 원한다고 가정한다.
메이븐의 핵심 플러그인은 소스코드컴파일, 배포 패키지, 웹사이트생성 및 기타 여러 프로세스에 대한 공통규칙이 적용된다.
정해진 규칙만 따른다면 메이븐을 사용하는데에 많은 노력을 필요로 하지않는다.
이러한 규칙들은 사용자가 요구사항에맞게 조정할수있어서, 특정방법이나 접근방식을 사용해야한다는 부작용을 느낄필요는 없다.
메이븐이 소프트웨어 빌드를 위한 공통인터페이스를 제공하기전에는 사용자정의된 빌드시스템 관리를 전담하는 사람이 따로 있었다.( 새 프로젝트의 특성에대해 배우기위해 소프트웨어 개발에서 시간을 할애해야했다.)
소프트웨어시스템이 점점 모듈화되어가고, 그에따라 빌드시스템에 복잡해지고 프로젝트수도 급증해가고있었고, 특정프로젝트의 빌드시스템을 파악하는데 약 1시간을 할당하기도했다.
메이븐이 성공한이유는 소프트웨어 빌드를 위한 공통인터페이스를 제공했다는 점이다.
메이븐은 XML문서를 구문분석하여 수명주기, 몇가지플러그인을 추적하는것외에 많은작업을 수행하는법은 모른다.
메이븐은 대부분 소스컴파일, 바이트코드 패키징, 빌드에서 발생해야하는 기타작업을 처리하는게 목적인 플러그인에서 발생한다.
메이븐은 war파일 패키징이나 Junit테스트 실행에대해서는 잘 모르고 이러한기능을 지원하는 플러그인은 maven respository에서 검색된다.
새로운 메이븐을 설치할때 대부분의 핵심 maven 플러그인을 가져오는데, 이는
메이븐의 배포다운로드 크기를 최소화하기위함 뿐 아니라, 플러그인을 업그레이드 하여 프로젝트 빌드에 기능을 추가할수있도록 하는 동작이다.
Junit을 예로들어 Junit3 에있던 기능을쓰다가 Junit4를 사용하려고할때, Maven구성파일의 버전변경을 제외하고는 프로젝트의 변경이 필요가없다는점이 가장중요하다.
플러그인이 원격저장소에서 다운되고, 유지관리된다는점이 메이븐 플러그인으로 범용성,재사용성을 누릴수있다는것을 의미한다.
메이븐은 프로젝트 오브젝트 모델(POM)을 유지관리한다.
소프트웨어프로젝트에 대한 설명을 개발하고, 프로젝트에 고유한 좌표세트를 할당한다.
의존성관리
원격저장소
메이븐 프로젝트, 의존성, 빌드, 아티팩트 들은 Project Object Model(POM)이라는 XML 파일에의해 설명된다.
POM은 메이븐이처리하는 프로젝트의종류, 소스에서 출력을생성하기위한 기본동작을 수정하는방법을 알려준다.
자바웹애플리케이션에 애플리케이션을 설명,구성및 사용자정의하는 web.xml이있는것처럼 메이븐프로젝트에는 pom.xml의 존재에 의해 정의된다.
외부파일의 속성을 로드한다던지, 임의의속성을 설정할수도있다.
General project information
프로젝트 이름, 프로젝트 URL, 후원 조직, 프로젝트 라이선스와 함께 개발자 및 기여자 목록이 포함된다.
Build settings
이 섹션에서는 기본 Maven 빌드의 동작을 사용자 정의하고, 소스 및 테스트의 위치를 변경할 수 있고, 새 플러그인을 추가하고, 플러그인 목표를 수명 주기에 첨부하고, 사이트 생성 매개변수를 사용자 정의할 수 있다.
Build environment
빌드 환경은 다양한 환경에서 사용하기 위해 활성화할 수 있는 프로필로 구성된다. 예를 들어, 개발 중에는 개발 서버에 배포하려는 반면 프로덕션에서는 프로덕션 서버에 배포하려고 하는 상황에 쓰일수있다.
POM relationships
프로젝트는 단독으로 존재하는 경우가 거의 없으며 다른 프로젝트에 종속되고 상위 프로젝트에서 POM 설정을 상속하며 자체 좌표를 정의하고 하위 모듈을 포함할 수 있다.
메이븐 설치의 일부인 Super POM이 존재한다.
자바의 java.lang.Object 클래스처럼 최상위 POM을 말한다.
모든 메이븐 프로젝트 POM들은 SuperPOM을 상속받는다.
메이븐 버전에는 프로젝트가 현재 개발중임을 나타내는 문자열 리터럴을 포함할수있다.
버전에 -SNAPSOT 문자열이 포함된경우 메이븐은 이 토큰을 UTC(세계시각)으로 변환된 날짜,시간으로 확장해서 그 프로젝트의 아티팩트를 메이븐 저장소에 배포하는경우
메이븐은 그 버전을 UTC에 맞춰서만든다. 즉, 스냅샷을 배포할때가아닌 특정시간의 소프트웨어 구성요소의 릴리스들을 만든다.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
다음과같이 scope을 지정할수있다.
메이븐의 장점중 하나로 의존성 전이가 있다.
a가 b에 의존하고 b는 c에의존하면 a는 c와 의존성이있는것으로 간주된다.
c가 d에 의존한다면 d또한 a의 의존성으로 간주된다.
Spring Framework와 같은것의 마지막 의존성까지 추적할필요가 없다는 소리다.
a가 b에 의존된경우 메이븐은 b가 a보다 먼저 빌드되어야한다는사실도 알고있다.
메이븐은 프로젝트와 상위모듈의관계 및 하위모듈의 관계를 모델링할수있다.
가장 일반적인 패키징 타입, 가장 흔히 접하게되는 라이프사이클 구성
jar + 추가사항이 포함된 패키징유형(디스크립터 파일을 생성 + 저장소 데이터 일부수정)
src/main/webapp/WEB-INF 디렉토리에 web.xml 구성이 필요함
SuperPOM에서 정의된 기본디렉토리위치를 사용자 정의하지않으면 메이븐이 /src/main/resources 에서
/target/classes 디렉토리로 파일을 복사한다.또한 리소스 필터링을 할수있는 능력도있다.
<build>
<filters>
<filter>src/main/filters/default.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
SuperPom에 정의된 기본값인 src/main/resources 에만 리소스가 있을필요는없다. 메이븐은 리소스 디렉토리도 추가할수있다.
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/xml</directory>
</resource>
<resource>
<directory>src/main/images</directory>
</resource>
</resources>
...
</build>
컴파일단계
super POM에 정의된값을 사용자정의하지않으면, compile:compile이 src/main/java 에서 target/classes 까지 모든것을 컴파일한다.
테스트컴파일단계
compile:testCompile 이 src/test/java 의 소스를 target/test-classes 디렉토리로 컴파일한다.
다양한 플랫폼에 맞게 빌드를 매우쉽게 커스텀할수있다.
reference: https://books.sonatype.com/mvnref-book/reference/index.html