Sự khác biệt trong maven giữa thẻ phụ thuộc và plugin trong pom xml là gì?


118

Tôi mới làm quen với công cụ maven, tôi đã thực hiện một dự án với Spring và Hibernate và chúng được định cấu hình trong pom.xml dưới dạng plugin, nhưng JUnit được gắn thẻ phụ thuộc. Câu hỏi của tôi là logic đằng sau một cái là plugin và một cái là phụ thuộc là gì?

Câu trả lời:


213

Cả hai plugin và phụ thuộc đều là tệp Jar.

Nhưng sự khác biệt giữa chúng là, hầu hết công việc trong maven được thực hiện bằng cách sử dụng các plugin; trong khi phần phụ thuộc chỉ là một tệp Jar sẽ được thêm vào classpath trong khi thực thi các tác vụ.

Ví dụ: bạn sử dụng một trình biên dịch-plugin để biên dịch các tệp java. Bạn không thể sử dụng trình biên dịch-plugin làm phụ thuộc vì điều đó sẽ chỉ thêm plugin vào classpath và sẽ không kích hoạt bất kỳ quá trình biên dịch nào. Các tệp Jar sẽ được thêm vào classpath trong khi biên dịch tệp, sẽ được chỉ định làm phụ thuộc.

Tương tự với kịch bản của bạn. Bạn phải sử dụng spring-plugin để thực thi một số tệp thực thi spring [Tôi không chắc spring-plugin được sử dụng để làm gì. Tôi chỉ phỏng đoán ở đây]. Nhưng bạn cần các phụ thuộc để thực thi các tệp thực thi đó. Và Junit được gắn thẻ phụ thuộc vì nó được sử dụng bởi plugin surefire để thực hiện các bài kiểm tra đơn vị.

Vì vậy, chúng ta có thể nói, plugin là một tệp Jar thực thi tác vụ và phụ thuộc là một Jar cung cấp các tệp lớp để thực thi tác vụ.

Hy vọng rằng câu trả lời câu hỏi của bạn!


Ai đó có thể cho tôi biết sự khác nhau giữa giai đoạn và mục tiêu trong thực hiện là gì không ?? Như tôi đã biết giai đoạn nói về vòng đời của maven .. nhưng tại sao lại là mục tiêu? bất kỳ gợi ý? Đôi khi tôi thấy mọi người đặt từ khóa vòng đời vào mục tiêu ... ??? (?.?)
taymedee

@taymedee câu hỏi SO này mô tả sự khác biệt: stackoverflow.com/questions/16205778/…
dev_feed,

1
@ r981 Câu trả lời của bạn cần phải rõ ràng hơn. Câu trả lời này tốt hơn: stackoverflow.com/questions/26292073/…
Digital Impermanence

Tôi nghĩ điểm thiếu sót của câu trả lời này là: các phần phụ thuộc cấp cao nhất chủ yếu được sử dụng bởi tạo tác của bạn thay vì các plugin.
miễn phí

3
@MichaelPacheco, Ý tôi là, spring-plugin sẽ thực hiện một nhiệm vụ nhất định là thực thi một bộ mã, có thể phụ thuộc vào một số thư viện, sẽ được chỉ định bởi 'phần phụ thuộc'. Lấy một ví dụ khác: bạn cần một trình biên dịch để thực thi một đoạn mã; Ở đây, trình biên dịch của bạn là một plugin và mã của bạn là tệp thực thi. Riêng trình biên dịch của bạn có khả năng thực thi bất kỳ mã nào, nhưng mã của bạn có thể phụ thuộc vào một thư viện, chẳng hạn như dấu phẩy apache, sẽ là một phụ thuộc. Trình biên dịch của bạn chỉ có thể biên dịch mã khi các phần phụ thuộc có trong classpath. Tôi hy vọng nó rõ ràng bây giờ.
r9891

37

Bản thân Maven có thể được mô tả là bộ xử lý thực phẩm có nhiều đơn vị khác nhau có thể được sử dụng để hoàn thành các nhiệm vụ khác nhau. Các đơn vị đó được gọi là plugin. Ví dụ, để biên dịch sử dụng maven dự án của bạn maven-compiler-plugin, để chạy các bài kiểm tra - maven-surefire-pluginv.v.

Sự phụ thuộc về mặt maven là một phần đóng gói của các lớp mà dự án của bạn phụ thuộc vào. Nó có thể là jar, war, v.v. Ví dụ, nếu bạn muốn có thể viết thử nghiệm JUnit, bạn sẽ phải sử dụng các chú thích và lớp JUnit, do đó bạn phải khai báo rằng dự án của bạn phụ thuộc vào JUnit.


cảm ơn vì đã trả lời nhanh, xin lỗi nhưng tôi vẫn còn bối rối vì tôi biết JUnit cũng là một khung công tác và (ngủ đông, mùa xuân) cũng chỉ có trong khuôn khổ, vì vậy có nghĩa là trong các trường hợp (ngủ đông, mùa xuân) cũng có thể được định cấu hình trong thẻ phụ thuộc ? tôi hy vọng bạn nhận được câu hỏi của tôi.
Coral

Có, và theo như tôi biết thì không có cái gọi là plugin Spring maven. Thông thường, Spring libs (hoặc Hibernate, hoặc JUnit, hoặc TestNG, v.v.) được khai báo là phụ thuộc cho dự án của bạn. Nếu bạn là người mới đến maven tôi khuyên bạn nên đọc này cuốn sách rất tốt.
Andrew Logvinov

@AndrewLogvinov - Tôi có một dự án multi pom để thử nghiệm tự động hóa api. Một trong những dự án maven có kiểm tra tự động hóa. Phần xây dựng của dự án pom chỉ có 1 plugin - plugin chắc chắn maven có tham chiếu đến một bộ. Toàn bộ thẻ xây dựng đã bị xóa. Bạn có thể vui lòng cho tôi biết điều này có nghĩa là gì? cảm ơn.
MasterJoe

15

Plugin và phụ thuộc là những thứ rất khác nhau và chúng bổ sung cho nhau.

Các plugin là gì?

Các plugin thực hiện các tác vụ cho một bản dựng Maven. Chúng không được đóng gói trong ứng dụng.

Đây là trái tim của Maven.
Bất kỳ tác vụ nào được Maven thực hiện đều được thực hiện bởi các plugin .
Có hai loại plugin: các buildvà các reportingplug-in :

  • Các plugin xây dựng sẽ được thực thi trong quá trình xây dựng và chúng phải được định cấu hình trong <build/>phần tử từ POM.
  • Các plugin báo cáo sẽ được thực thi trong quá trình tạo trang web và chúng phải được định cấu hình trong <reporting/phần tử> từ POM.

Theo mục tiêu maven quy định tại các dòng lệnh (ví dụ mvn clean, mvn clean packagehay mvn site), một lifecyle cụ thể sẽ được sử dụng và một tập hợp cụ thể các mục tiêu bổ sung sẽ được thực thi.
Có ba built-in xây dựng vòng đời: default, cleansite. Vòng defaultđời xử lý việc triển khai dự án của bạn, cleanvòng đời xử lý việc dọn dẹp dự án, trong khi sitevòng đời xử lý việc tạo tài liệu trang web của dự án của bạn.

Mục tiêu plugin có thể bị ràng buộc với một giai đoạn cụ thể của một phong cách sống cụ thể.
Ví dụ maven-compiler-pluginvới phím tắt theo mặc định các compilemục tiêu giai đoạn vòng đời: compile.
Hầu hết các plugin maven (cả plugin chính và plugin của bên thứ ba) đều ưu tiên quy ước hơn là cấu hình. Vì vậy, chúng thường ràng buộc mục tiêu plugin vào một giai đoạn cụ thể để làm cho việc sử dụng chúng đơn giản hơn.

Nó gọn gàng hơn và ít bị lỗi hơn:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
</plugin>

hơn:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
  <executions>
    <execution>
        <phase>compile</phase>
        <goals>
            <goal>compile</goal>
        </goals>
    </execution>
  </executions>
</plugin>

Phụ thuộc là gì?

Sự phụ thuộc là các tạo tác / thành phần Maven được yêu cầu trong classpath trong quá trình xây dựng Maven.
Chúng có thể được đóng gói trong ứng dụng nhưng không nhất thiết (xem phần scopebên dưới).

Phần lớn các phụ thuộc là jar nhưng đây cũng có thể là các loại lưu trữ khác: war, ear, test-jar, ejb-client ... hoặc vẫn là POM hoặc BOM.
Trong một pom.xml, các phụ thuộc có thể được chỉ định ở nhiều nơi: <build><dependencies>part, dependencies managementpart hoặc vẫn trong một pluginkhai báo ! Thật vậy, một số plugin có thể cần phải có một số phụ thuộc vào classpath trong quá trình thực thi của chúng. Điều đó không phổ biến nhưng điều đó có thể xảy ra.
Dưới đây là một ví dụ từ tài liệu cho thấy điều đó plugindependencycó thể hoạt động cùng nhau:

Ví dụ: Plugin Maven Antrun phiên bản 1.2 sử dụng phiên bản Ant 1.6.5, nếu bạn muốn sử dụng phiên bản Ant mới nhất khi chạy plugin này, bạn cần thêm <dependencies>phần tử như sau:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.2</version>
        ...
        <dependencies>
          <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.1</version>
          </dependency>
          <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant-launcher</artifactId>
            <version>1.7.1</version>
          </dependency>
         </dependencies>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Trong Maven, phụ thuộc được tham chiếu trong một định dạng cụ thể:
groupId:artifactId:packaging:classifier:version.
Bộ phân loại (tùy chọn) và đóng gói ( JARtheo mặc định) thường không được chỉ định. Vì vậy, các định dạng phổ biến trong dependencykhai khá: groupId:artifactId:version.
Đây là một ví dụ về phụ thuộc được khai báo trong <build><dependencies>phần:

<build>
   <dependencies>
      <dependency>
         <groupId>org.hibernate</groupId>
         <artifactId>hibernate-core</artifactId>
         <version>5.2.14.Final</version>
      </dependency>
   <dependencies>
</build>

Trái ngược với một plugin, một phụ thuộc có một phạm vi.
Phạm vi mặc định là compile. Đó là phạm vi cần thiết phổ biến nhất (quy ước lại cấu hình).
Các compilephạm vi có nghĩa là phụ thuộc có sẵn trong tất cả các classpaths của một dự án.

Phạm vi xác định trong đó phụ thuộc classpaths sẽ được thêm vào. Ví dụ: chúng ta cần nó lúc biên dịch và thời gian chạy, hay chỉ để biên dịch và thực thi thử nghiệm?

Ví dụ: trước đây chúng tôi đã định nghĩa Hibernate là một compilephụ thuộc vì chúng tôi cần nó ở mọi nơi: biên dịch nguồn, biên dịch thử nghiệm, thời gian chạy, v.v.
Nhưng chúng tôi không muốn rằng các thư viện thử nghiệm có thể được đóng gói trong ứng dụng hoặc được tham chiếu trong mã nguồn . Vì vậy, chúng tôi chỉ định testphạm vi cho chúng:

<build>
   <dependencies>
     <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.1.0</version>
        <scope>test</scope>
     </dependency>
   <dependencies>
</build>

lời giải thích tuyệt vời !, vì tôi không thành thạo với việc thiết lập các phụ thuộc trong Java, tôi vẫn còn nghi ngờ, tôi hiện đang làm việc trong IntelliJ và đã tạo một dự án maven, khi tôi cố gắng đưa vào, webdriver-ietôi có hai tùy chọn, hoặc bao gồm nó như pluginshoặc dependency, tôi bao gồm cả hai để so sánh, và quan sát thấy cả hai đều giống hệt nhau, groupIdđiểm khác biệt duy nhất là pluginskhông đi kèm với một phiên bản cụ thể nhưng dependencyđi kèm 0.6.685. Bạn có thể giải thích nó trong các thuật ngữ giáo dân (liên quan đến ví dụ này) sự khác biệt là gì, cái nào nên sử dụng khi nào. Bất kì lời đề nghị nào?
Anu

1
Khó có thể đưa ra câu trả lời chính xác nhất mà không thấy của bạn pom.xml. Nhưng một điều mà bạn nên quan tâm là việc chỉ định phiên bản phụ thuộc là bắt buộc (trong pom hiện tại hoặc trong pom mẹ nếu nó là phụ thuộc kế thừa) trong bất kỳ phiên bản Maven nào kể từ Maven 3 (có lẽ là một ý tưởng tồi như một tính năng), chỉ định phiên bản plugin là tùy chọn. Maven sẽ sử dụng phiên bản cuối cùng có sẵn trong kho lưu trữ phát hành nơi Maven tìm thấy nó. (1/2)
davidxxx

1
Lưu ý rằng đó là một cách không tốt để chỉ định một plugin. Nó không làm cho bản dựng của bạn có thể tái tạo theo thời gian ( cwiki.apache.org/confluence/display/MAVEN/… ). Bạn sẽ thấy một cảnh báo trong bản dựng. Vì vậy, sự khác biệt là gì ?". Các plugin thực hiện các tác vụ cho một bản dựng Maven trong khi phần phụ thuộc là các thư viện (jar hoặc bất cứ thứ gì) cần thiết trong classpath trong quá trình xây dựng. Nếu việc xây dựng của dự án của bạn là như nhau bất kể trường hợp (sử dụng thư viện hoặc cách plugin), nó có nghĩa là các plugin là không nơi nương tựa như không được sử dụng (2/2).
davidxxx

6

Nếu bạn đến từ nền tảng front-end như tôi và quen thuộc với Grunt và npm, hãy nghĩ về nó như sau:

Trước tiên, bạn sẽ chạy, nói npm install grunt-contrib-copy --save-dev,. Điều này giống như của maven <dependency></dependency>. Nó tải xuống các tệp cần thiết để thực hiện tác vụ xây dựng.

Sau đó, bạn sẽ cấu hình nhiệm vụ trong Gruntfile.js

copy: {
  main: {
    src: 'src/*',
    dest: 'dest/',
  },
}

Điều này giống như của maven <plugin>/<plugin>. Bạn đang cho công cụ xây dựng biết phải làm gì với mã được tải xuống bởi npm / <dependency></dependency>.

Tất nhiên đây không phải là một phép loại suy chính xác, nhưng đủ gần để giúp bạn quấn lấy nó.


4

Các trình cắm được sử dụng để thêm các chức năng cho Mavenchính nó (như thêm eclipsehỗ trợ hoặc SpringBoothỗ trợ cho Mavenv.v.). Mã nguồn của bạn cần có sự phụ thuộc để vượt qua bất kỳ giai đoạn Maven nào ( compilehoặc teství dụ). Trong trường hợp JUnitvì mã kiểm tra về cơ bản là một phần của cơ sở mã của bạn và bạn gọi JUnitcác lệnh cụ thể bên trong các bộ kiểm tra và các lệnh đó không được cung cấp do Java SDKđó JUnitphải có mặt tại thời điểm Mavenđang trong giai đoạn kiểm tra và điều này được xử lý bằng cách đề cập đến JUnitnhư một phụ thuộc trong pom.xmltệp của bạn .


1

Trái tim của Maven là một khung thực thi plugin - theo định nghĩa nhỏ gọn chính thức và tiêu chuẩn. Để làm rõ hơn, các lệnh bạn sử dụng như maven-install/clean/compile/build etcđể tạo / thực thi các chum, đôi khi chúng tôi cũng chạy theo cách thủ công. Vì vậy, những thứ bạn muốn chạy (hoặc cấu hình hoặc thực thi) về cơ bản, bạn đặt chúng vào thẻ phụ thuộc của mavens pom và câu trả lời cho ai sẽ chạy các phụ thuộc này (cần thiết cho thiết lập môi trường) là các plugin.

        javac (compiler) dependency.java (dependency) 

1

Câu trả lời một dòng - hiểu cơ bản

Plugin là một công cụ bạn sử dụng khi thực hiện bản dựng maven của mình

Sự phụ thuộc có nghĩa là loại thư viện bất kỳ mà bạn sẽ sử dụng trong mã của mình


0

Plugin là một phần mở rộng của Maven, một thứ được sử dụng để tạo ra tạo tác của bạn (ví dụ: maven-jar-plugin, được sử dụng để, bạn đoán nó, tạo một jar từ các lớp và tài nguyên đã biên dịch của bạn).

Phần phụ thuộc là một thư viện cần thiết cho ứng dụng bạn đang xây dựng, tại thời điểm biên dịch và / hoặc kiểm tra và / hoặc thời gian chạy.

plugin và phụ thuộc

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.