Mavenは私を何百回も虐待して、私はMavenを初恋のように待っています.
4777 ワード
前言
現在のインターネットプロジェクト開発において,特にJava分野では,Mavenが随所に見られるといえる.Mavenの倉庫管理、依存管理、継承と集約などの特性はプロジェクトの構築に完璧な解決策を提供し、もしあなたがMavenを理解していないならば、1つのマルチモジュールのプロジェクトはあなたを悩ませるのに十分で、依存衝突はあなたを困惑させ、プロジェクトがどのように運行されているのかさえ分からないと言ってもいい.
Thinking in Maven
思い出してみると、JDKをインストールすると配置Maven(MAVEN_HOME、path)がインストールされ、settingsを修正する必要がある可能性が高い.xmlファイル、例えばローカル倉庫のアドレスパスを変更します.例えば、settingsにcopyを設定する可能性があります.xmlでは(私服のいくつかの構成である可能性が高い).次に、IDEAまたはEclipseでMavenプラグインの構成を行い、エンジニアリングのpomで使用できます.xmlにはラベルを追加してjarパッケージを管理し始め、Maven仕様のディレクトリ構造の下でコードを記述し、最後にプラグインでテスト、パッケージング(jar or war)、導入、実行を行います.
Mavenの使い方について説明しましたが、以下では考えてみましょう.
Maven倉庫構成
jarパッケージが必要です.毎回インターネットでダウンロードすることはできません.大変ですね.だから、地元の倉庫はjarパッケージのキャッシュを追加することに相当します.まずここで調べてください.ここで調べられない場合は、私服に行って探し、私服も見つからない場合は、中央倉庫に行って探し、jarを見つけたら、jarの情報を私服と地元の倉庫に同期します.私服は、社内のローカルエリアネットワークのサーバーです.あなたのプロジェクトProject-Aが他の人のProject-Bのインタフェースに依存しているとき、どうすればいいか考えてみてください.Mavenがない場合は、もちろんcopy Project-B jarをローカルlibに導入します.Mavenの方法は、Project-B deployを私服倉庫に使用するために他の人が必要であることは明らかです.私服に当社の内部専用jarが格納されているからです!それだけでなく、私服は中央倉庫の鏡像として機能しており、はっきり言えば代理店です! 中央倉庫:この倉庫はインターネット上のjarを格納し、Mavenチームが維持し、住所は:http://repo1.maven.org/maven2/.
Q 2:使用について座標配置 依存管理 実はこのラベルはjarの検索座標:groupId、artifactId、versionを明らかにしています.
一般的には、私服にartifactIdを入力して検索したり、http://search.maven.org/、http://mvnrepository.com/に表示されます. versionは開発バージョン(Snapshot)とリリースバージョン(Release)に分かれていますが、なぜ分けますか?
実際の開発では、AサービスがBサービスに依存する、AとBが同時に開発され、Bが開発中にBUGを発見し、修正後、バージョンを1.0から2.0にアップグレードすると、AもPOMに従う必要があるというシーンによく遭遇する.XMLでバージョンアップを行います.数日後、Bはまた問題を発見し、修正してアップグレードバージョンを発表し、Aにアップグレードを通知しました.これは開発中のバージョンの不安定さがこのような問題を招いたと言える.
Mavenは、Snapshotバージョンを使用して、開発中にBがリリースしたバージョンがSnapshotバージョンとしてマークされ、Aが依存するときにSnapshotバージョンを選択すると、Bがリリースされるたびに、私服倉庫でタイムスタンプ付きSnapshotバージョンが形成され、Aが構築されるとBの最新タイムスタンプのSnapshotバージョンが自動的にダウンロードされます!
Q 3:Mavenが依存管理を行った以上、なぜ依存競合が発生するのか.依存衝突を処理する手段は?
まず、Mavenにとって、同じグループIdと同じartifactIdでは、1つのversionしか使用できません!上図の依存順に従って、1.2バージョンのjarが使用されます.
今、私たちは考えることができて、例えば工事の中でA、Bを導入する必要があって、Aは1.0バージョンのCに依存して、Bは2.0バージョンのCに依存して、それでは問題が来て、Cの使用するバージョンはA、Bを導入する順序によって決まりますか?これは明らかに頼りにならない!Aの依存がBの依存の後に書かれている場合、最終的に1.0バージョンのCが導入されたことを意味し、実行段階でクラス(ClassNotFoundException)、メソッド(NoSuchMethodError)で見つからないエラー(Bは高バージョンのCを使用しているため)が発生する可能性が高い!
ここでは,依存伝達(transitive),Mavenの最近の依存戦略の2つの概念について言及した.依存伝達:AがBに依存し、BがCに依存する場合、Aが導入され、BとCが導入されることを意味する. Mavenの最近の依存ポリシー:1つのプロジェクトが同じgroupId、artifactIdの複数のバージョンに依存する場合、依存ツリー(mvn dependency:tree)でプロジェクトに最も近いバージョンが使用されます.(ここからMavenはちょっと問題があるのではないでしょうか.高バージョンの依存を選択できますか.Gradleはversion+ポリシーであることがわかります) 今、依存衝突をどのように処理するかを考えてみましょう.アイデア1:どのバージョンを使用するかは明らかですが、伝達にどのように依存してもバージョンロックを行うことができますか?
[主にサブモジュールに使用されるバージョンの一貫性]を使用します.考え方2:依存伝達の中で、私たちが依存したくないものを取り除くことができますか?
[実際にはIDEAでプラグインを直接利用して生成を支援できます]を使用します.アイデア3:最近の依存ポリシーである以上、明示的な依存指定バージョンを直接使用するのは、プロジェクトに最も近いのではないでしょうか.
使用
Q 4:依存のベストプラクティスを導入し、問題を事前に発見
工事の中で、私たちはいくつかの依存を加える必要があることを避けることができなくて、依存を加えた後に運行する時やっと依存の衝突が解決していることを発見して、少し遅いようです!では、事前に問題を発見できますか?
もし私たちが新しく依存を追加したら、まずmvn dependency:treeコマンドによって依存ツリーを形成し、私たちが新しく追加した依存があるかどうか、伝達依存があるかどうか、伝達依存があるかどうか、依存ツリーのバージョンと衝突があるかどうか、複数のバージョンの衝突がある場合は、上記の方法で解決します.
Q 5:Maven正規化ディレクトリ構造
ここで注意しなければならないのは2点です.第一:src/mainの下の内容は最終的にJar/Warにパッケージされ、src/testの下はテスト内容であり、パッケージされません. 第2:src/main/resourcesのリソースファイルは、Mavenのデフォルトのライフサイクルの所定の動作であるターゲットディレクトリにCOPYされます.(考えてみればhibernate/mybatisのマッピングXMLはresourcesの下に置く必要があり、他の場所に置くことはできません) Q 6:Mavenのライフサイクル
後のコマンドを実行すると、前のコマンドが自動的に実行されることに注意してください.
実際、私たちが最もよく使っているのは、 clean:問題があるから、たくさん片付けなさい. package:Jar or Warパッケージにすると、clean+compile が自動的に実行されます. install:ローカルエンジニアリングJarをローカルウェアハウス にアップロード deploy:私服 にアップロード
Q 7:scope依存範囲について
Mavenのライフサイクルにコンパイル、テスト、実行のプロセスがある以上、junitなどのテストにのみ依存していることは明らかです.コンパイルに依存しても使えないものもありますが、mysqlのドライバパッケージはコンパイル期間では使えません(コンパイル期間はJDBCインタフェースを使用します)、実行時に使用されます.コンパイル期間は使用され、実行期間は提供されない依存もあります.servlet-apiなどのコンテナはtomcatで提供されているので、コンパイル期間の提供だけが必要です.
まとめて言えば、
compile:デフォルトのscopeで、実行期間が有効で、パッケージに打ち込む必要があります.
provided:コンパイル期間は有効で、実行期間は提供する必要はなく、パッケージには入力されません.
runtime:コンパイルは必要ありません.実行期間が有効で、パッケージにインポートする必要があります.(インタフェースと実装の分離)
test:テストが必要で、パッケージには入らない.
System:非ローカルウェアハウスがシステムのパスの下に導入され、存在するjar.(一般的には使用しません)
寄り添って歩まないで、千里までありません;小流を積まなければ,川の海になることはできない.
現在のインターネットプロジェクト開発において,特にJava分野では,Mavenが随所に見られるといえる.Mavenの倉庫管理、依存管理、継承と集約などの特性はプロジェクトの構築に完璧な解決策を提供し、もしあなたがMavenを理解していないならば、1つのマルチモジュールのプロジェクトはあなたを悩ませるのに十分で、依存衝突はあなたを困惑させ、プロジェクトがどのように運行されているのかさえ分からないと言ってもいい.
Thinking in Maven
思い出してみると、JDKをインストールすると配置Maven(MAVEN_HOME、path)がインストールされ、settingsを修正する必要がある可能性が高い.xmlファイル、例えばローカル倉庫のアドレスパスを変更します.例えば、settingsにcopyを設定する可能性があります.xmlでは(私服のいくつかの構成である可能性が高い).次に、IDEAまたはEclipseでMavenプラグインの構成を行い、エンジニアリングのpomで使用できます.xmlにはラベルを追加してjarパッケージを管理し始め、Maven仕様のディレクトリ構造の下でコードを記述し、最後にプラグインでテスト、パッケージング(jar or war)、導入、実行を行います.
Mavenの使い方について説明しましたが、以下では考えてみましょう.
Maven倉庫構成
jarパッケージが必要です.毎回インターネットでダウンロードすることはできません.大変ですね.だから、地元の倉庫はjarパッケージのキャッシュを追加することに相当します.まずここで調べてください.ここで調べられない場合は、私服に行って探し、私服も見つからない場合は、中央倉庫に行って探し、jarを見つけたら、jarの情報を私服と地元の倉庫に同期します.
Q 2:使用について
org.projectlombok
lombok
1.12.6
一般的には、私服にartifactIdを入力して検索したり、http://search.maven.org/、http://mvnrepository.com/に表示されます.
実際の開発では、AサービスがBサービスに依存する、AとBが同時に開発され、Bが開発中にBUGを発見し、修正後、バージョンを1.0から2.0にアップグレードすると、AもPOMに従う必要があるというシーンによく遭遇する.XMLでバージョンアップを行います.数日後、Bはまた問題を発見し、修正してアップグレードバージョンを発表し、Aにアップグレードを通知しました.これは開発中のバージョンの不安定さがこのような問題を招いたと言える.
Mavenは、Snapshotバージョンを使用して、開発中にBがリリースしたバージョンがSnapshotバージョンとしてマークされ、Aが依存するときにSnapshotバージョンを選択すると、Bがリリースされるたびに、私服倉庫でタイムスタンプ付きSnapshotバージョンが形成され、Aが構築されるとBの最新タイムスタンプのSnapshotバージョンが自動的にダウンロードされます!
Q 3:Mavenが依存管理を行った以上、なぜ依存競合が発生するのか.依存衝突を処理する手段は?
まず、Mavenにとって、同じグループIdと同じartifactIdでは、1つのversionしか使用できません!上図の依存順に従って、1.2バージョンのjarが使用されます.
今、私たちは考えることができて、例えば工事の中でA、Bを導入する必要があって、Aは1.0バージョンのCに依存して、Bは2.0バージョンのCに依存して、それでは問題が来て、Cの使用するバージョンはA、Bを導入する順序によって決まりますか?これは明らかに頼りにならない!Aの依存がBの依存の後に書かれている場合、最終的に1.0バージョンのCが導入されたことを意味し、実行段階でクラス(ClassNotFoundException)、メソッド(NoSuchMethodError)で見つからないエラー(Bは高バージョンのCを使用しているため)が発生する可能性が高い!
ここでは,依存伝達(transitive),Mavenの最近の依存戦略の2つの概念について言及した.
[主にサブモジュールに使用されるバージョンの一貫性]を使用します.
[実際にはIDEAでプラグインを直接利用して生成を支援できます]を使用します.
使用
Q 4:依存のベストプラクティスを導入し、問題を事前に発見
工事の中で、私たちはいくつかの依存を加える必要があることを避けることができなくて、依存を加えた後に運行する時やっと依存の衝突が解決していることを発見して、少し遅いようです!では、事前に問題を発見できますか?
もし私たちが新しく依存を追加したら、まずmvn dependency:treeコマンドによって依存ツリーを形成し、私たちが新しく追加した依存があるかどうか、伝達依存があるかどうか、伝達依存があるかどうか、依存ツリーのバージョンと衝突があるかどうか、複数のバージョンの衝突がある場合は、上記の方法で解決します.
Q 5:Maven正規化ディレクトリ構造
ここで注意しなければならないのは2点です.
後のコマンドを実行すると、前のコマンドが自動的に実行されることに注意してください.
実際、私たちが最もよく使っているのは、
Q 7:scope依存範囲について
Mavenのライフサイクルにコンパイル、テスト、実行のプロセスがある以上、junitなどのテストにのみ依存していることは明らかです.コンパイルに依存しても使えないものもありますが、mysqlのドライバパッケージはコンパイル期間では使えません(コンパイル期間はJDBCインタフェースを使用します)、実行時に使用されます.コンパイル期間は使用され、実行期間は提供されない依存もあります.servlet-apiなどのコンテナはtomcatで提供されているので、コンパイル期間の提供だけが必要です.
まとめて言えば、
compile:デフォルトのscopeで、実行期間が有効で、パッケージに打ち込む必要があります.
provided:コンパイル期間は有効で、実行期間は提供する必要はなく、パッケージには入力されません.
runtime:コンパイルは必要ありません.実行期間が有効で、パッケージにインポートする必要があります.(インタフェースと実装の分離)
test:テストが必要で、パッケージには入らない.
System:非ローカルウェアハウスがシステムのパスの下に導入され、存在するjar.(一般的には使用しません)
寄り添って歩まないで、千里までありません;小流を積まなければ,川の海になることはできない.