2009-12-08 45 views
46

OSGi cho phép các phụ thuộc được xác định thông qua Import-Package, chỉ kết nối một gói duy nhất (được xuất từ ​​bất kỳ gói nào) và Require-Bundle, kết nối tới một gói được đặt tên cụ thể.Khi nào tôi nên sử dụng Gói-Nhập khẩu và khi nào tôi nên sử dụng Yêu cầu-Gói?

Khi xây dựng ứng dụng OSGi trên greenfield, tôi nên sử dụng phương pháp nào để đại diện cho các phụ thuộc? Hầu hết các gói sẽ là nội bộ, nhưng sẽ có một số phụ thuộc vào các gói bên ngoài (nguồn mở).

+4

Từ http://eclipsesource.com/blogs/2009/07/14/why-i-cant-recommend-using-import-package/: “Nhìn, Yêu cầu-Bundle là thứ đã được sử dụng trong Eclipse cho một thời gian, chủ yếu là vì lý do di sản. Chúng tôi khuyên bạn không nên sử dụng nó nữa. Import-Package tốt hơn nếu bạn muốn ghép nối lỏng hơn giữa các bó. Tuy nhiên, hãy lưu ý đến các gói phân chia đau có thể gây ra. ” –

Trả lời

45

Tôi tin rằng Require-Bundle là một điều Eclipse (mà bây giờ đã làm cho nó trong thông số OSGi để chứa Eclipse). Cách OSGi "thuần túy" là sử dụng Import-Package, vì nó tách riêng gói đó khỏi gói cung cấp nó. Bạn nên khai báo các phụ thuộc vào chức năng mà bạn cần (API Java được cung cấp bởi một phiên bản nhất định của một gói nhất định) thay vì chức năng đó đến từ đâu (điều này không quan trọng đối với bạn). Điều này giúp thành phần của các gói linh hoạt hơn.

Tương tự JavaScript: Điều này giống như phát hiện xem trình duyệt web có hỗ trợ một API nhất định hay không so với chuỗi chuỗi tác nhân người dùng cho biết loại trình duyệt đó là gì.

Peter Kriens của Liên minh OSGi có nhiều điều để nói về điều này trên số OSGi blog.

Có lẽ trường hợp duy nhất bạn cần sử dụng Require-Bundle là nếu bạn có các gói phân tách, đó là gói được trải rộng trên nhiều gói. Tất nhiên, các gói chia đều không được khuyến khích.

+2

Cả Yêu cầu-Gói và Nhập-Gói được xác định trong thông số OSGi; không có biến thể "thuần khiết" của hai. – AlBlue

+2

@AlBlue: cập nhật câu trả lời của tôi để làm cho nó rõ ràng hơn rằng trong khi Yêu cầu-Bundle là trong spec, nó chỉ làm cho nó có khả năng tương thích với Eclipse. – Thilo

+6

Tôi nghĩ Thilo đúng. Như Peter Kriens đã đề cập trong bài viết: "Yêu cầu-Bundle có một sự hấp dẫn trực quan rất khó để phủ nhận." Nhưng nó không cần thiết buộc các bó lại với nhau. Trong thế giới Java, tôi sẽ so sánh nó với IoC và tìm kiếm trực tiếp phụ thuộc. Một ví dụ phụ thuộc vào gói 'commons-logging' so với gói API' commons-logging'.Trong trường hợp thứ hai, bạn có thể dễ dàng hoán đổi gói 'common-logging' với gói adapter SLF4J thích hợp cũng xuất gói API' commons-logging' và do đó liền mạch tạo cầu từ 'commons-logging' thành SLF4J. –

3

Tôi tin rằng Gói nhập cho bạn khớp nối lỏng lẻo hơn và nên được ưu tiên hơn. Tôi sử dụng nó khi khai báo các phụ thuộc vào các gói mà tôi không sở hữu, chẳng hạn như slf4j và tôi có thể trao đổi các triển khai như tôi muốn. Tôi sử dụng Require-Bundle khi sự phụ thuộc là thứ mà tôi có thể kiểm soát, chẳng hạn như các gói của riêng tôi, bởi vì bất kỳ thay đổi quan trọng nào cũng sẽ tự mình trải qua.

-1

Tôi không tin rằng việc sử dụng gói nhập là tốt hơn, bởi vì kỳ vọng mặc định của tôi khi làm việc với một gói là làm việc với API công cộng được liên kết. Vì lý do đó, Require-Bundle có ý nghĩa hơn.

+5

Tuyên bố này không có ý nghĩa. Lý do của bạn là lý do bạn sẽ sử dụng Gói nhập thay vì Yêu cầu-Gói. Đối phó với API công khai và đừng lo lắng về việc ai cung cấp nó. Bạn không làm việc với gói, bạn làm việc với API. – Robin

13

Ủng hộ gói ưu đãi hơn Yêu cầu gói.

Yêu cầu-Bundle:

  • xác định bó rõ ràng (và phiên bản) để sử dụng. Nếu một gói requirde cần phải được tái cấu trúc và một gói được di chuyển ở nơi khác, thì người phụ thuộc sẽ cần những thay đổi đối với MANIFEST.MF
  • của chúng tôi cung cấp cho bạn quyền truy cập vào tất cả các gói xuất, bất kể chúng là gì và bất kể bạn có cần chúng hay không . Nếu các bộ phận bạn không cần có phụ thuộc của riêng mình, bạn sẽ cần những phụ kiện đó cho các gói phụ thuộc của riêng mình, bạn sẽ cần những gói đó cho các gói
  • được xuất lại
  • , cho phép sử dụng các gói phân tách, ví dụ: gói trải rộng trên nhiều gói
  • có thể được sử dụng cho các phụ thuộc không phải mã, ví dụ: tài nguyên, trợ giúp, v.v.

nhập trọn gói:

  • lỏng khớp nối, chỉ gói (và phiên bản) được chỉ định và thời gian chạy tìm bó cần
  • triển khai thực tế có thể được swaped ra
  • phụ thuộc các gói có thể được chuyển đến các gói khác nhau bởi chủ sở hữu gói
  • Nhưng yêu cầu duy trì thêm siêu dữ liệu (nghĩa là: mỗi tên gói) ở mức độ chi tiết thấp hơn
+0

Đối với gói nhập, nếu bạn cần một phiên bản cụ thể của gói nhưng gói thực sự có phiên bản trong đó thì sao? AFAIK, gói java không có phiên bản. –

0

Import-Package nên tốt hơn bởi vì, như đã nói ở trên, bạn có thể di chuyển một gói từ một bó khác mà không thay đổi MANIFEST.MF khách hàng hiện có của

Nhưng ...

Có một lý do thực tế để sử dụng Require-Bundle nếu bạn đang sử dụng Eclipse để phát triển các gói của mình:

Eclipse không sử dụng các gói làm đơn vị độ phân giải. Nó sử dụng bó. Tức là, nếu bạn sử dụng một gói của một gói, Eclipse biên dịch gói của bạn mà không báo cáo bất kỳ vấn đề nào với việc sử dụng phần còn lại của các gói không được nhập từ gói đó.

Bạn có thể (bạn là con người) nghĩ rằng mọi thứ đều ổn và tải lên gói của bạn để triển khai nhưng ... gói của bạn sẽ bị gián đoạn khi chạy.

Tôi chắc chắn về điều đó vì sự cố này đã xảy ra (với tôi!) Hôm nay.

Giải pháp tốt là thay đổi container classpath của Eclipse nhưng ... nếu điều này sẽ không được thực hiện ... bạn có thể quyết định tránh loại vấn đề này đòi hỏi bó, thay vì gói, trả giá đã đề cập (không có chuyển động mã tương thích ngược giữa các bó).

0

Tránh nhập gói. Khi các gói cung cấp nhiều mối quan hệ giữa các bó, chúng dễ bị các chu kỳ phụ thuộc khó phát hiện và tránh.

Mặt khác, yêu cầu nhóm tham chiếu một gói duy nhất, làm cho biểu đồ phụ thuộc được bảo vệ khỏi chu kỳ bằng kiểm tra thời gian xây dựng nhỏ. Với Require-Bundle, việc xây dựng kiến ​​trúc nhiều lớp dễ dàng hơn với mức trừu tượng thấp hơn được cô lập.

Các vấn đề liên quan