سؤال

ماهو الفرق بين dependencyManagement و dependencies؟ لقد رأيت المستندات في موقع Apache Maven على الويب. يبدو أن التبعية محددة بموجب dependencyManagement يمكن استخدامها في وحداتها الفرعية دون تحديد الإصدار.

علي سبيل المثال:

يحدد مشروع الوالدين (PRO-PAR) التبعية بموجب dependencyManagement:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8</version>
    </dependency>
 </dependencies>
</dependencyManagement>

ثم في طفل Pro-Par ، يمكنني استخدام Junit:

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
 </dependencies>

ومع ذلك ، أتساءل عما إذا كان من الضروري تحديد Junit في POM الأصل؟ لماذا لا تحددها مباشرة في الوحدة النمطية المطلوبة؟

هل كانت مفيدة؟

المحلول

إدارة التبعية يسمح بدمج ومركزية إدارة إصدارات التبعية دون إضافة تبعيات ورثها جميع الأطفال. هذا مفيد بشكل خاص عندما يكون لديك مجموعة من المشاريع (أي أكثر من واحد) الذي يرث أحد الوالدين المشتركين.

حالة استخدام مهمة للغاية dependencyManagement هو التحكم في إصدارات القطع الأثرية المستخدمة في التبعيات المتعدية. من الصعب شرح هذا بدون مثال. لحسن الحظ ، يتضح هذا في الوثائق.

نصائح أخرى

لقد تأخرت بشكل عصري لهذا السؤال ، لكنني أعتقد أن الأمر يستحق استجابة أكثر وضوحًا من الاستجابة المقبولة (وهذا صحيح ، لكنه لا يؤكد على الجزء المهم الفعلي ، الذي تحتاجه لاستنتاج نفسك).

في POM الوالد ، الفرق الرئيسي بين <dependencies> و <dependencyManagement> هذا هو:

القطع الأثرية المحددة في <dependencies> سيتم تضمين القسم دائمًا على أنه تبعية للوحدة النمطية للطفل.

القطع الأثرية المحددة في <dependencyManagement> القسم ، سيتم تضمينه فقط في وحدة الطفل إذا تم تحديدها أيضًا في <dependencies> قسم من وحدة الطفل نفسها. لماذا تسأل؟ نظرًا لأنك تحدد الإصدار و/أو النطاق في الوالد ، ويمكنك تركها عند تحديد التبعيات في بوم الطفل. يمكن أن يساعدك ذلك في استخدام إصدارات موحدة لتبعيات وحدات الأطفال ، دون تحديد الإصدار في كل وحدة طفل.

ال توثيق على موقع Maven فظيع. ما تفعله الإدارة هو ببساطة تحريك تعريفات التبعية الخاصة بك (الإصدار ، والاستثناءات ، وما إلى ذلك) حتى POM الأصل ، ثم في بومس الطفل ، عليك فقط وضع مجموعة المجموعة والتحف. هذا كل شيء (باستثناء تسلسل POM POM وما شابه ، لكن هذا ليس معقدًا حقًا أيضًا - يفوز إدارة التبعية على التبعيات على مستوى الوالدين - ولكن إذا كان لديك سؤال حول ذلك أو الواردات ، فإن وثائق Maven أفضل قليلاً).

بعد قراءة كل القمامة "A" و "B" و "C" على موقع Maven والارتباك ، أعيد كتابة مثالهم. لذلك إذا كان لديك مشروعان (Proj1 و Proj2) يشتركان في التبعية المشتركة (betashared) ، فيمكنك تحريك تلك التبعية إلى POM الأصل. أثناء وجودك فيه ، يمكنك أيضًا رفع أي تبعيات أخرى (Alpha و Charlie) ولكن فقط إذا كان من المنطقي لمشروعك. لذلك بالنسبة للموقف الموضح في الجمل السابقة ، إليك الحل مع إدارة التبعية في POM الوالد:

<!-- ParentProj pom -->
<project>
  <dependencyManagement>
    <dependencies>
      <dependency> <!-- not much benefit defining alpha here, as we only use in 1 child, so optional -->
        <groupId>alpha</groupId>
        <artifactId>alpha</artifactId>
        <version>1.0</version>
        <exclusions>
          <exclusion>
            <groupId>zebra</groupId>
            <artifactId>zebra</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      <dependency>
        <groupId>charlie</groupId> <!-- not much benefit defining charlie here, so optional -->
        <artifactId>charlie</artifactId>
        <version>1.0</version>
        <type>war</type>
        <scope>runtime</scope>
      </dependency>
      <dependency> <!-- defining betaShared here makes a lot of sense -->
        <groupId>betaShared</groupId>
        <artifactId>betaShared</artifactId>
        <version>1.0</version>
        <type>bar</type>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

<!-- Child Proj1 pom -->
<project>
  <dependencies>
    <dependency>
      <groupId>alpha</groupId>
      <artifactId>alpha</artifactId>  <!-- jar type IS DEFAULT, so no need to specify in child projects -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId>
      <artifactId>betaShared</artifactId>
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>

<!-- Child Proj2 -->
<project>
  <dependencies>
    <dependency>
      <groupId>charlie</groupId>
      <artifactId>charlie</artifactId>
      <type>war</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId> 
      <artifactId>betaShared</artifactId> 
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>

إنه كما قلت. dependencyManagementيستخدم لسحب جميع معلومات التبعية إلى ملف POM مشترك ، مما يؤدي إلى تبسيط المراجع في ملف POM الطفل.

يصبح مفيدًا عندما يكون لديك سمات متعددة لا ترغب في إعادة إعادة النمط في مشاريع الأطفال المتعددة.

أخيراً، dependencyManagement يمكن استخدامها لتحديد إصدار قياسي من قطعة أثرية لاستخدامها عبر مشاريع متعددة.

لا يزال هناك شيء واحد لم يتم تسليط الضوء عليه بما فيه الكفاية ، في رأيي ، وهذا هو الميراث غير المرغوب فيه.

إليك مثال تدريجي:

أعلن في بلدي parent بوم:

<dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>
</dependencies>

فقاعة! لدي في بلدي Child A, Child B و Child C الوحدات النمطية:

  • ضمنية ورثها بومس الطفل
  • مكان واحد للإدارة
  • لا حاجة لإعادة صياغة أي شيء في بومس الطفل
  • لا يزال بإمكاني إعادة الرعاية والتجاوز version 18.0 في Child B إذا أردت.

ولكن ماذا لو انتهى بي الأمر إلى عدم الحاجة إلى الجوافة Child C, ولا في المستقبل Child D و Child E وحدات؟

سيظلون يرثونه وهذا غير مرغوب فيه!يشبه هذا تمامًا رائحة رمز كائن جافا ، حيث ترث بعض البتات المفيدة من الفصل ، ودرد من الأشياء غير المرغوب فيها أيضًا.

هذا هو المكان <dependencyManagement> يأتي دور. عندما تضيف هذا إلى POM الوالد ، كل وحدات طفلك توقف عن رؤيته. وبالتالي أنت قسري للذهاب إلى كل وحدة فردية تحتاج إليها وإعلانها مرة أخرى (Child A و Child B, ، بدون الإصدار رغم ذلك).

ومن الواضح أنك لا تفعل ذلك Child C, ، وبالتالي تظل الوحدة النمطية هزيلة.

هناك بعض الإجابات التي تحدد الاختلافات بين <depedencies> و <dependencyManagement> العلامات مع Maven.

ومع ذلك ، فقد تم وضع بعض النقاط أدناه بطريقة موجزة:

  1. <dependencyManagement> يسمح بدمج جميع التبعيات (المستخدمة على مستوى POM للأطفال) المستخدمة عبر وحدات مختلفة - وضوح, إدارة نسخة التبعية المركزية
  2. <dependencyManagement> يسمح بسهولة للترقية/خفض التبعيات بناءً على الحاجة ، في السيناريو الآخر ، يجب ممارسته على كل مستوى بوم طفل - التناسق
  3. التبعيات المقدمة في <dependencies> يتم استيراد العلامة دائمًا ، في حين أن التبعيات المقدمة في <dependencyManagement> في الوالدين ، لن يتم استيراد POM إلا إذا كان لدى الطفل POM دخوله كله <dependencies> بطاقة شعار.

إذا تم تحديد التبعية في عنصر الإدارة التبعي لـ POM على المستوى الأعلى ، فلن يضطر مشروع الطفل إلى سرد إصدار التبعية بشكل صريح. إذا قام مشروع الطفل بتحديد إصدار ، فسيتجاوز الإصدار المدرج في قسم إدارة التبعية في POM. وهذا يعني أن إصدار الإدارة التبعية يستخدم فقط عندما لا يعلن الطفل نسخة مباشرة.

آسف أنا متأخر جدا للحزب.

اسمحوا لي أن أحاول شرح الفرق باستخدام mvn dependency:tree أمر

النظر في المثال أدناه

PORTER POM - مشروعي

<modules>
    <module>app</module>
    <module>data</module>
</modules>

<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>
</dependencyManagement>

طفل بوم - وحدة البيانات

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
</dependencies>

POM الطفل - وحدة التطبيق (ليس لها تبعية إضافية ، لذلك ترك التبعيات فارغة)

 <dependencies>
</dependencies>

على الجري mvn dependency:tree الأمر ، نحصل على النتيجة التالية

Scanning for projects...
------------------------------------------------------------------------
Reactor Build Order:

MyProject
app
data

------------------------------------------------------------------------
Building MyProject 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ MyProject ---
com.iamvickyav:MyProject:pom:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building app 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ app ---
com.iamvickyav:app:jar:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building data 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ data ---
com.iamvickyav:data:jar:1.0-SNAPSHOT
+- org.apache.commons:commons-lang3:jar:3.9:compile
\- com.google.guava:guava:jar:19.0:compile

Google Guava يتم إدراجها على أنها تبعية في كل وحدة (بما في ذلك الوالدين) ، في حين أباتشي العموم يتم إدراجها على أنها تبعية فقط في وحدة البيانات (ولا حتى في الوحدة الأصل)

في POM الوالد ، الفرق الرئيسي بين <dependencies> و <dependencyManagement> هذا هو:

القطع الأثرية المحددة في <dependencies> سيتم تضمين القسم دائمًا على أنه تبعية للوحدة النمطية للطفل.

سيتم تضمين القطع الأثرية المحددة في القسم فقط في وحدة الطفل إذا تم تحديدها أيضًا في قسم الوحدة النمطية للطفل نفسها. لماذا تسأل؟ نظرًا لأنك تحدد الإصدار و/أو النطاق في الوالد ، ويمكنك تركها عند تحديد التبعيات في بوم الطفل. يمكن أن يساعدك ذلك في استخدام إصدارات موحدة لتبعيات وحدات الأطفال ، دون تحديد الإصدار في كل وحدة طفل.

في Eclipse ، هناك ميزة أخرى في dependencyManagement. متى dependencies يتم استخدامه بدونه ، ويلاحظ التبعيات التي لا أساس لها في ملف POM. لو dependencyManagement يتم استخدامه ، تظل التبعيات التي لم يتم حلها دون أن يلاحظها أحد في ملف POM وتظهر الأخطاء فقط في ملفات Java. (الواردات ومثل ...)

من الأفضل إحضار الفرق بين الاثنين إلى ما يبدو ضروريًا وكافيًا لعنصر إدارة التبعية المتاح في مستندات موقع Maven:

الإدارة

"معلومات التبعية الافتراضية للمشاريع التي ترث من هذا المشروع. لم يتم حل التبعيات في هذا القسم على الفور. بدلاً من ذلك ، عندما تعلن POM المستمدة من هذا القسم عن تبعية موصوفة من قبل مجموعة متطابقة و Artifactid ، الإصدار والقيم الأخرى من هذا القسم تستخدم لهذا التبعية إذا لم يتم تحديدها بالفعل ". [ https://maven.apache.org/ref/3.6.1/maven-model/maven.html ]

يجب قراءتها مع بعض المعلومات المتاحة على صفحة مختلفة:

".. الحد الأدنى من المعلومات لمطابقة مرجع التبعية مقابل قسم إدارة التبعية هو في الواقع {groupid ، artifactid ، type ، classifier}. في كثير من الحالات ، ستشير هذه التبعيات إلى قطع أثرية جرة بدون مصنف. يتيح لنا ذلك اختصار الهوية التي تم تعيينها على {groupid ، artifactid} ، لأن الافتراضي لحقل النوع هو جرة ، والمصنف الافتراضي لاغية. " [https://maven.apache.org/guides/introduction/introduction-to-dependency-michanism.html ]

وبالتالي ، فإن جميع العناصر الفرعية (النطاق ، والاستثناءات ، إلخ ،) لعنصر التبعية-بخلاف المجموعة ، والقطع الأثرية ، والنوع ، والمصنف ، وليس فقط الإصدار-متاح للقفل/الافتراضي عند النقطة (وبالتالي موروثة من هناك فصاعدًا) يمكنك تحديد التبعية ضمن التبعية. إذا قمت بتحديد تبعية مع العناصر الفرعية من النوع والمصنف (راجع صفحة الويب الأولى المذكورة للتحقق من جميع العناصر الفرعية) باعتبارها جرة وليس خالية على التوالي ، فأنت بحاجة إلى {groupid ، artifactid ، مصنف ، اكتب} للرجوع (حل) أن التبعية في أي وقت في ميراث ينشأ من عنصر الإدارة التبعية. آخر ، {GroupId ، Artifactid} كافية إذا كنت لا تنوي تجاوز الإعدادات الافتراضية للمصنف والنوع (جرة و NULL على التوالي). لذا فإن الافتراضي هو كلمة رئيسية جيدة في هذا التعريف ؛ أي عناصر فرعية (بخلاف GroupID ، artifactid ، المصنف والنوع ، بالطبع) تم تعيينها بشكل صريح في القيمة (النقطة التي تشير إليها تبعية التبعية الافتراضية في عنصر إدارة التبعية.

لذلك ، يتم حل أي عنصر تبعية خارج إدارة التبعية ، سواء كإشارة إلى بعض عناصر إدارة التبعية أو كقائمة مستقلة على الفور (أي مثبتة على المستودع المحلي ومتاح لل classpaths).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top