728x90
반응형

POM.xml: Maven 기반 프로젝트의 핵심 설정 파일

POM.xml 개요

POM(Project Object Model)은 Maven 프로젝트의 구조와 내용을 설명하는 XML 파일로, 프로젝트 빌드 프로세스의 중심에 위치합니다. 이 파일은 프로젝트 의존성, 빌드 설정, 플러그인 등을 정의하며 Maven이 프로젝트를 어떻게 구성하고 빌드할지 결정하는 중요한 역할을 담당합니다.

POM.xml의 기본 구조

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 기타 설정 요소들 -->
</project>

필수 POM 요소

  1. modelVersion: POM 모델 버전(현재 4.0.0이 표준)
  2. groupId: 프로젝트 그룹 식별자(일반적으로 조직 도메인의 역순)
  3. artifactId: 프로젝트 결과물 식별자
  4. version: 프로젝트 버전(릴리스: 1.0, 개발 중: 1.0-SNAPSHOT)

이 세 요소(groupId, artifactId, version)는 Maven 저장소 내에서 프로젝트를 고유하게 식별하는 좌표 역할을 합니다.

선택적 POM 요소

  1. packaging: 패키징 방식(jar, war, ear 등, 기본값: jar)
  2. name: 프로젝트 이름
  3. description: 프로젝트 설명
  4. url: 프로젝트 웹사이트 URL
  5. properties: 프로젝트에서 사용할 속성 정의
  6. dependencies: 프로젝트 의존성 정의
  7. build: 빌드 설정(디렉토리, 플러그인 등)

의존성 관리

Maven의 가장 강력한 기능 중 하나는 의존성 관리입니다. pom.xml 파일에서 의존성을 선언하면 Maven이 자동으로 필요한 라이브러리를 다운로드하고 프로젝트에 포함시킵니다.

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.9</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

의존성 스코프(Scope)

의존성 스코프는 해당 라이브러리가 프로젝트의 어느 단계에서 필요한지를 지정합니다:

  1. compile: 기본값, 컴파일 및 런타임에 필요
  2. provided: 컴파일 시에만 필요(런타임에는 외부에서 제공됨, 예: 서블릿 API)
  3. runtime: 런타임에만 필요(컴파일에는 불필요, 예: JDBC 드라이버)
  4. test: 테스트 컴파일 및 실행에만 필요(예: JUnit)
  5. system: provided와 유사하나 Maven 중앙 저장소가 아닌 명시적 경로에서 JAR 파일 제공
  6. import: 다른 POM의 의존성 관리 섹션을 가져올 때 사용

의존성 전이(Transitive Dependencies)

Maven은 선언된 의존성이 필요로 하는 다른 라이브러리들도 자동으로 가져오는 의존성 전이 기능을 제공합니다. 이는 복잡한 프로젝트에서 의존성 관리를 크게 단순화합니다.

의존성 충돌 해결

동일 라이브러리의 다른 버전이 필요할 경우 Maven은 다음 규칙으로 충돌을 해결합니다:

  1. 최단 경로 우선: 의존성 트리에서 가장 가까운 버전 선택
  2. 먼저 선언된 의존성 우선: 동일한 거리에 있는 경우 pom.xml에 먼저 선언된 버전 선택

필요한 경우 명시적으로 의존성을 제외할 수 있습니다:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.9</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

프로퍼티 설정

pom.xml에서 속성을 정의하여 재사용할 수 있습니다:

<properties>
    <java.version>11</java.version>
    <spring.version>5.3.9</spring.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>

빌드 설정

build 섹션에서는 소스 코드 위치, 리소스, 플러그인 등 빌드 과정에 필요한 다양한 설정을 정의합니다:

<build>
    <sourceDirectory>src/main/java</sourceDirectory>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

프로파일 설정

다양한 환경(개발, 테스트, 운영)에 따라 다른 설정을 적용할 수 있는 프로파일 기능을 제공합니다:

<profiles>
    <profile>
        <id>development</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <db.url>jdbc:mysql://localhost:3306/devdb</db.url>
        </properties>
    </profile>
    <profile>
        <id>production</id>
        <properties>
            <db.url>jdbc:mysql://prod-server:3306/proddb</db.url>
        </properties>
    </profile>
</profiles>

프로파일은 다음과 같이 활성화할 수 있습니다:

mvn clean install -Pproduction

상속과 모듈화

부모 POM 상속

대규모 프로젝트에서는 공통 설정을 부모 POM에 정의하고 하위 프로젝트에서 상속받아 사용할 수 있습니다:

<!-- 자식 pom.xml -->
<project>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>parent-project</artifactId>
        <version>1.0.0</version>
    </parent>

    <artifactId>child-module</artifactId>
    <!-- 부모에서 groupId와 version을 상속받음 -->
</project>

멀티 모듈 프로젝트

대형 프로젝트는 여러 모듈로 나누어 관리할 수 있습니다:

<!-- 부모 pom.xml -->
<project>
    <groupId>com.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <modules>
        <module>module-core</module>
        <module>module-web</module>
        <module>module-api</module>
    </modules>
</project>

의존성 관리 최적화

대규모 프로젝트에서는 dependencyManagement 섹션을 사용하여 의존성 버전을 중앙에서 관리할 수 있습니다:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>5.3.9</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- 버전을 명시하지 않아도 위에서 관리되는 버전 사용 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
</dependencies>

Maven 라이프사이클과 POM.xml

Maven은 기본적으로 다음과 같은 라이프사이클을 가지며, pom.xml의 설정에 따라 각 단계가 실행됩니다:

graph TD
    A[validate] --> B[compile]
    B --> C[test]
    C --> D[package]
    D --> E[verify]
    E --> F[install]
    F --> G[deploy]

각 단계는 pom.xml에 정의된 플러그인과 설정에 따라 동작합니다.

실제 활용 사례

Spring Boot 프로젝트의 POM.xml

Spring Boot 프로젝트는 일반적으로 spring-boot-starter-parent를 상속받아 사용합니다:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.4</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

이렇게 설정하면 Spring Boot의 의존성 관리 기능을 통해 호환되는 라이브러리 버전을 자동으로 선택하여 사용할 수 있습니다.

마이크로서비스 아키텍처에서의 POM.xml

마이크로서비스 아키텍처에서는 공통 부모 POM을 정의하고 각 서비스별 모듈이 이를 상속받는 구조를 자주 사용합니다:

graph TD
    A[parent-pom] --> B[common-library]
    A --> C[service-discovery]
    A --> D[api-gateway]
    A --> E[user-service]
    A --> F[order-service]
    A --> G[payment-service]

이 구조에서 parent-pom은 모든 마이크로서비스가 공유하는 의존성과 플러그인을 정의하고, 각 서비스는 자신에게 필요한 특정 의존성만 추가하는 방식으로 구성됩니다.

결론

pom.xml은 Maven 기반 Java 프로젝트의 중심이 되는 설정 파일로, 프로젝트의 구조와 의존성을 선언적으로 관리할 수 있게 해줍니다. 적절하게 구성된 pom.xml은 빌드 프로세스를 자동화하고, 의존성 관리를 단순화하며, 일관된 프로젝트 구조를 유지하는 데 크게 기여합니다. 대규모 엔터프라이즈 애플리케이션에서 작은 오픈소스 라이브러리에 이르기까지, pom.xml은 Java 개발 생태계의 핵심 요소로 자리 잡고 있습니다.

Keywords

POM, Maven, dependency management, 빌드 자동화, XML configuration, 프로젝트 구조, 의존성 관리, 라이프사이클, 멀티모듈, 빌드 프로세스

728x90
반응형

+ Recent posts