Maven
Maven はクロスプラットフォームのプロジェクト管理ツールです。主に Java プラットフォーム上のプロジェクト構築、依存関係の管理、プロジェクト情報の管理に使われます。
Maven の役割:
- プロジェクト構築:標準化された、クロスプラットフォームの自動ビルド方式を提供する
- 依存関係管理:プロジェクトが依存するリソース(jar パッケージ)を簡単に管理し、リソース間のバージョン衝突を避ける
- 開発構造の統一:標準化された、統一的なプロジェクト構造を提供する
基本概念
プロジェクトオブジェクトモデル(POM)
POM(Project Object Model)は Maven プロジェクトの中心となるファイルです。ファイル名は pom.xml です。開発者はこのファイルで、プロジェクトの基本情報、依存関係、関連するビルドタスクやプラグインを定義します。Maven は pom.xml の定義に従って、対応するビルドタスクを実行します。POM ファイルには主に次の要素があります。
- GAVP 属性:
groupId(プロジェクトグループ ID)、artifactId(プロジェクト成果物 ID)、version(プロジェクトバージョン)、packaging(パッケージ形式)を含む。 - 依存関係(dependencies):プロジェクトに必要なライブラリやフレームワーク依存を宣言するために使う。各依存にはグループ ID、成果物 ID、バージョンなどの情報が含まれる。
- ビルド要素(build):プロジェクトのビルド情報と、ビルド中の各種タスクを含む。
- プラグイン要素(plugins):Maven のプラグインシステムを使ってビルド処理を拡張する。各プラグインにはプラグイングループ ID、プラグイン成果物 ID、バージョン、設定情報などが含まれる。
- 環境設定要素(profiles):異なる環境に応じて、プロジェクトに別々のビルド設定を行う。
- プロパティ要素(properties):グローバルプロパティを定義する。POM 内で参照でき、POM ファイルの保守性と可読性を高める。
依存関係管理
依存関係管理は Maven の中心的な機能の一つです。依存項目を定義する標準的な方法を提供し、それらの依存を自動でダウンロードし、依存間の衝突を解決します。依存関係管理を使うと、手動で依存をダウンロード、インストールする手間を避けられ、プロジェクトのビルドと開発の流れを簡単にできます。
pom.xml ファイルでは、依存要素を使ってプロジェクトに必要な依存項目を宣言できます。依存項目には通常、groupId、artifactId、version が含まれ、ライブラリやフレームワークのバージョンを一意に識別します。また、compile、test、provided などの依存スコープを使い、ビルド中に Maven が依存をどう扱うかを決められます。
ビルドライフサイクル
Maven のライフサイクルは、ビルド処理の標準ステップを定義します。プロジェクト構築中に Maven が実行する操作と順序を決めています。Maven には三つのライフサイクルがあります。clean ライフサイクル、default ライフサイクル、site ライフサイクルです。
- clean ライフサイクル:プロジェクトディレクトリをクリーンにするために使う。プロジェクト出力ディレクトリ、テスト出力ディレクトリ、一時ファイルなどを削除する。
- default ライフサイクル:プロジェクト構築の中心となるライフサイクル。コンパイル、テスト、パッケージ化などを含む。デフォルトでは、Maven が
packageフェーズまで実行されると、ソースコードをコンパイルし、テストし、パッケージ化し、成果物をローカル Maven リポジトリに公開する。 - site ライフサイクル:プロジェクトドキュメントとサイトを生成するために使う。HTML ドキュメントや静的サイトの生成などを含む。
プラグイン管理
Maven のプラグイン管理も重要な機能です。プラグインを中心に Maven のビルドライフサイクルを拡張し、よく使うビルド機能や特定のビルド機能を提供します。Maven プラグインには、組み込みプラグインと外部プラグインがあります。組み込みプラグインは Maven ビルドの基本機能をサポートします。たとえば maven-compiler-plugin は Java コードのコンパイルに使い、maven-jar-plugin はプロジェクトを JAR ファイルにパッケージ化するために使います。外部プラグインは Maven 中央リポジトリや他のリポジトリから取得して使えます。
マルチモジュールプロジェクトのサポート
Maven はマルチモジュールプロジェクトの作成をサポートし、大規模プロジェクトの構成と管理を簡単にします。マルチモジュールプロジェクトでは、依存、プラグイン、プロパティ設定を共有でき、プロジェクト設定と保守がしやすくなります。マルチモジュールプロジェクトを使うと、複雑な Java プロジェクトをより整理して管理できます。
まとめると、Maven の基本概念には POM、依存関係管理、ビルドライフサイクル、プラグイン管理、マルチモジュールプロジェクトのサポートなどがあります。これらの概念が Maven の中心機能を作り、Java プロジェクトの構築と管理を便利で効率的にします。
モジュール分割開発と設計
意味:元のモジュールを機能ごとに複数のモジュールへ分割し、モジュール間の呼び出しやインターフェース共有をしやすくします。
- たとえば、従来の三層アーキテクチャ +
domainのパッケージ構造では、domainを共通モジュールとして切り出す。 - 元のモジュールと同じ階層に新しいモジュールを作成し、パッケージ構造を一致させる。
- その中に
domainのコードを書く。 - Maven コマンドでモジュールをローカルリポジトリにインストールする(
install)。 domainモジュールをserverモジュールに導入する。
注意:チーム内開発では、モジュール機能をチーム内で共有できるリポジトリ(プライベートリポジトリ)に公開する必要があります。
依存
依存関係管理
依存とは、現在のプロジェクトの実行に必要な jar を指します。一つのプロジェクトには複数の依存を設定できます。
形式:
<!-現在のプロジェクトが依存するすべてのjarを設定する-->
<dependencies>
<!-具体的な依存を設定する-->
<dependency>
<!-依存が属するグループid-->
<groupId></groupId>
<!-依存が属するプロジェクトid-->
<artifactId></artifactId>
<!-依存バージョン-->
<version></version>
</dependency>
</dependencies>依存の推移
依存には推移性があります。
- 直接依存:現在のプロジェクトで依存設定によって作られた依存関係。POM ファイルに書くもの。
- 間接依存:依存先のリソースが他のリソースに依存している場合、現在のプロジェクトはそのリソースにも間接的に依存する。
依存推移の衝突
依存推移の衝突問題:
- パス優先:依存に同じリソースが現れた場合、階層が深いほど優先度は低く、階層が浅いほど優先度は高い。
- 宣言優先:同じ階層で同じリソースに依存している場合、設定順が前のものが後ろのものを上書きする。
- 特別優先:同じ階層で同じリソースの異なるバージョンが設定された場合、後に設定したものが先に設定したものを上書きする。
オプション依存と除外依存
参照している一部のリソースを呼び出し側に伝播させたくない場合、オプション依存 を使えます。
dependency タグの中に <optional>true</optional> を書きます。
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<optional>true</optional>
</dependency>
</dependencies>オプション依存は、現在のプロジェクトが依存しているリソースを隠します。
隠されたリソースは、推移性を持たなくなります。
子モジュールに依存があり、親モジュールで参照したくない場合は、上の方法以外にもう一つの方法があります。
それが除外依存です。
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<!-除外依存は、現在のリソースに対応する依存関係を隠す-->
<exclusions>
<exclusion>
<groupId></groupId>
<artifactId></artifactId>
<!-注意:除外ではバージョン指定は不要-->
</exclusion>
<exclusion>
</exclusion>
</exclusions>
</dependency>
</dependencies>除外する依存リソースは GA だけを指定すればよく、V を指定する必要はありません。
まとめると、オプション依存は機能使用の選択性に重点があります。除外依存は、既存の依存関係に含まれる不要な依存を取り除くことに重点があります。
継承と集約
集約
複数のモジュールを一つの全体としてまとめ、同時にプロジェクトをビルドする処理を集約と呼びます。
集約プロジェクト:
- 通常は業務機能を持たない「空」のプロジェクトです。POM ファイルだけを持ちます。
役割:
- 集約プロジェクトを使うと、複数のプロジェクトをグループ化できます。集約プロジェクトをビルドすることで、含まれるモジュールをまとめてビルドできます。
方法:
- 一つのモジュールを作成し、
dependenciesタグを削除する。 - このプロジェクトは、他のプロジェクトとパッケージ方式が異なる。
<!-管理するモジュール名を設定する-->
<modules>
<module></module>
<module></module>
<module></module>
</modules>
<!-このタグを追加し、このモジュールをpomとしてパッケージ化する-->
<packaging>pom</packaging>注意:各 Maven プロジェクトには対応するパッケージ方式があります。デフォルトは jar で、Web プロジェクトのパッケージ方式は war です。
注意:集約プロジェクトに含まれるモジュールは、ビルド時にモジュール間の依存関係によってビルド順が決まります。集約プロジェクト内でのモジュール設定の記述順とは関係ありません。
集約に参加するプロジェクトは、自分が集約に参加しているかを上位へ感知できません。どのモジュールをこのプロジェクトの集約に参加させるかを下位に設定するだけです。
大きなプロジェクトを先に作り、その中に複数の小さなプロジェクトを作ってビルドするイメージです。
継承
二つのプロジェクト間の関係です。Java と似ており、子プロジェクトは親プロジェクトの設定情報を継承できます。依存関係の継承でよく使われます。
役割:
- 設定を簡単にする
- バージョン衝突を減らす
<!-Javaと同じく、継承関係は子クラス(子モジュール)で宣言する-->
<!-現在のプロジェクトがparentプロジェクトを継承するように設定する-->
<parent>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!-parent工程路径-->
<relativePath>../XXX/pom.xml</relativePath>
</parent>設定後、共通の依存リソースを親プロジェクト(root)に抽出できます。
依存関係管理
親プロジェクトでは依存関係管理を定義できます。
<!-依存関係管理を定義する-->
<dependencyManagement>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</dependency>
</dependencyManagement>この部分の依存は、子プロジェクト にとっては 選択可能な依存 です。使いたい場合は必ず宣言する必要があります。
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<!-子プロジェクトではバージョンを書く必要がなくなり、親プロジェクトが統一して提供する-->
</dependency>子プロジェクトでは、親プロジェクトに定義されていない依存関係も定義できます。
集約と継承の違い
役割:
集約はプロジェクトを素早くビルドするために使う
継承は設定を素早く行うために使う
共通点:
- 集約と継承の
pom.xmlファイルはどちらもパッケージ方式がpomであり、二つの関係を同じpomファイルに作れる - 集約と継承はいずれも設計型モジュールであり、実際のモジュール内容はない
- 集約と継承の
相違点:
- 集約は現在のモジュール内で関係を設定する。集約は、どのモジュールが集約に参加しているかを感知できる
- 継承は子モジュール内で関係を設定する。親モジュールは、どの子モジュールが自分を継承しているかを感知できない
プロパティ
バージョンの統一管理
バージョンを変数として設定し、version タグのところで変数を参照するイメージです。
<!--プロパティを定義する-->
<properties>
<spring-version>5.2.10.RELEASE</spring-version>
<junit.version>4.12</junit.version>
</properties><!--プロパティを使う-->
<groupId></groupId>
<artifactId></artifactId>
<version>${spring.version}</version>今後、すべての依存バージョンは プロパティ に書くことが推奨されます。
バージョン番号
プロジェクトバージョン
- SNAPSHOT(スナップショットバージョン)
- プロジェクト開発中に一時的に出力されるバージョンをスナップショットバージョンと呼ぶ
- スナップショットバージョンは開発の進行に合わせて継続的に更新される
- RELEASE(リリースバージョン)
- プロジェクト開発が一定のマイルストーンに到達した後、チーム外部へ公開する比較的安定したバージョン。このバージョンに対応するビルドファイルは安定しており、その後の機能開発を行っても現在のリリース内容は変わらない。このようなバージョンをリリースバージョンと呼ぶ。
リリースバージョン
- alpha 版
- beta 版
- 純数字版
複数環境設定
Maven は複数環境の設定を提供します。開発者が使用中に環境を素早く切り替えられるようにするためです。
<!--複数環境を設定する-->
<profiles>
<!--開発環境-->
<profile>
<id>env_dep</id>
<roperties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url>
</roperties>
<!--デフォルト起動環境にするかを設定する-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--本番環境-->
<profile>
<id>env_pro</id>
<roperties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url>
</roperties>
</profile>
<!--テスト環境-->
<profile>
<id>env_test</id>
<roperties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url>
</roperties>
</profile>
</profiles>ビルド時には、コマンドで環境を選択できます。mvn コマンド -P 環境定義id
mvn install -P pro_envテストをスキップする
使用場面:
- 機能更新がまだ完成していない
- 素早くパッケージ化したい
方式一:
IDEA の Maven 欄で 稲妻 ボタンをクリックする。
またはビルドコマンドに mvn コマンド -D skipTests を入力する。
mvn install -D skipTests方式二:
<build>
<plugins>
<!--テストプラグイン-->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
<!--テストに参加する内容を選択する。上はtrueにする必要がある-->
<includes>
<include>**/BookServiceTest.java</include>
</includes>
<!--テストに参加しない内容を選択する。上はfalseにする必要がある-->
<excludes>
<exclude>**/BookServiceTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>プライベートリポジトリ
独立したサーバーです。チーム内部のリソース共有とリソース同期の問題を解決するために使います。
Nexus
Nexus:Sonatype 社の Maven プライベートリポジトリ 製品です。
ダウンロード先:https://help.sonatype.com/en/download.html
サーバー起動:nexus-3.70.3-01\bin ディレクトリで実行します。
nexus.exe /run nexusサーバーへアクセス(デフォルトポート 8081):localhost:8081

基本設定情報を変更する:
- インストールパス下の
etcディレクトリにあるnexus-default.propertiesファイルには、nexusの基本設定情報が保存されています。たとえばデフォルトのアクセスポートです。
サーバー実行設定情報を変更する:
- インストールパス下の
binディレクトリにあるnexus.vmoptionsファイルには、nexusサーバー起動時の設定情報が保存されています。たとえばデフォルトの使用メモリ容量です。
プライベートリポジトリの分類
- ホストリポジトリ(hosted)の役割と機能
- 役割
- リソース統合:企業内部のソフトウェア資産の保存場所です。自社開発成果と許可されたサードパーティリソースを統合し、集中管理しやすくします。リソースが各開発者の端末に分散することを避けます。
- 内部共有:チーム内部の協力を促進します。異なるプロジェクトチームの開発者が、開発済みのコンポーネントやツールを簡単に取得でき、コード再利用率が上がります。
- 機能
- リソース保存と管理:安全で信頼できる保存領域を提供し、開発者がソフトウェアリソースをアップロード、更新、削除できるようにします。アクセス権限も設定でき、許可された人だけがリソースを操作できます。
- バージョン管理:各リソースのバージョン変化を記録し、開発者が履歴バージョンを確認したり、古いバージョンへ戻したりできます。ソフトウェア保守と問題調査で重要です。
- 役割
- プロキシリポジトリ(proxy)の役割と機能
- 役割
- ダウンロード高速化:ローカルキャッシュと中央リポジトリの橋渡しをし、外部中央リポジトリからリソースをダウンロードする時間を減らし、開発効率を高めます。
- ネットワーク最適化:企業内部ネットワークから外部リポジトリへの頻繁なアクセスを減らし、帯域を節約します。同時に、外部ネットワークの不安定さや中央リポジトリ障害が内部開発へ与える影響を減らします。
- 機能
- キャッシュ管理:中央リポジトリからダウンロードしたリソースを自動でキャッシュし、キャッシュサイズや有効期限などのルールに従って管理できます。
- プロキシリクエスト:内部開発者のダウンロードリクエストを受け取り、リソースがキャッシュ済みかを判断します。キャッシュ済みなら直接返し、なければ中央リポジトリから取得してキャッシュした後に返します。
- 役割
- リポジトリグループ(group)の役割と機能
- 役割
- 操作の簡略化:開発者は複数リポジトリのアドレスやアクセス方法を個別に覚える必要がありません。リポジトリグループを使うと、複数の関連リポジトリをまとめられます。開発者はリポジトリグループからダウンロードするだけで、グループが内部の複数リポジトリから自動でリソースを探します。
- 統一管理:管理者側では、関連リポジトリ群に対して権限設定やリソース配分をまとめて行いやすくなります。たとえば、テスト用リポジトリと開発用リポジトリを一つのリポジトリグループにまとめ、アクセス権限を統一管理できます。
- 機能
- リソース検索と位置特定:開発者がリソースを要求すると、リポジトリグループは事前に定義した順序で、含まれる各リポジトリを検索し、マッチするリソースが見つかるまで探します。
- リポジトリ統合:異なる種類(ホストリポジトリやプロキシリポジトリなど)または異なる用途のリポジトリを一つの論理単位にまとめ、ダウンロードなどの操作で連携させます。
- 役割
まとめ:
| リポジトリ種類 | 英語名 | 機能 | 関連操作 |
|---|---|---|---|
| ホストリポジトリ | hosted | 自社開発 + サードパーティリソースを保存する | アップロード |
| プロキシリポジトリ | proxy | 中央リポジトリへ代理接続する | ダウンロード |
| リポジトリグループ | group | リポジトリをグループ化してダウンロード操作を簡単にする | ダウンロード |
リソースのアップロードとダウンロード
IDEA はまず jar パッケージをローカルリポジトリに置き、その後プライベートリポジトリへアップロードします。
ダウンロードも、プライベートリポジトリからローカルリポジトリへダウンロードします。
プライベートリポジトリへアクセスするユーザー名 / パスワード
ダウンロード先アドレス(リポジトリグループアドレス)
そのため、ローカルリポジトリ側で設定する必要があります。Maven インストールディレクトリの -conf-settings.xml に設定します。
<!--プライベートリポジトリ権限を設定する-->
<server>
<id>私服中的服务器id名称</id>
<username>用户名/username>
<password>密码</password>
</server><!--プライベートリポジトリアクセスパスを設定する-->
<mirror>
<!--リポジトリグループid-->
<id>mirrorId</id>
<mirrorOf>*</mirrorOf>
<url>http://my.repository.com/repo/path</url>
</mirror>pom で、現在のプロジェクトをどのリポジトリへ公開するかを設定します。
<!--現在のプロジェクトがプライベートリポジトリに保存される具体的な位置を設定する-->
<distributionManagement>
<repository>
<id>name-release</id>
<url>http://localhost:8081/repository/name-release/</url>
</repository>
<snapshotRepository>
<id>name-snapshot</id>
<url>http://localhost:8081/repository/name-snapshot/</url>
</snapshotRepository>
</distributionManagement>公開コマンド:mvn deploy
