Sự khác biệt giữa phạm vi @ApplicationScoped và @Singleton trong CDI là gì?


92

Trong CDI có phạm vi @ApplicationScopedvà ( javax.inject) @Singletongiả. sự khác biệt giữa chúng là gì? Bên cạnh thực tế @ApplicationScopedlà proxied, và @Singletonkhông.

Tôi có thể thay đổi @Singletonbean của mình thành @ApplicationScopedkhông? Có thể @ApplicationScopedđậu có hai (hoặc nhiều) ví dụ?


11
Bạn đã đọc tài liệu tham khảo về Weld chưa? Có một số giải thích về sự khác biệt thực tế giữa @ApplicationScoped@Singletontại phần 5.4 (trang 36).
brandizzi

3
Tôi cũng tìm ra bản tóm tắt những khác biệt ở phần cuối của bài viết này germanescobar.net/2010/04/... hữu ích
mờ freake

1
bạn đang đề cập đến phạm vi Singleton nào - javax.ejb hay javax.inject?
John Ament

Câu trả lời:


29

@Singletonkhông phải là một phần của đặc điểm kỹ thuật CDI. Nó là một phần của EJB và javax.inject(JSR-330). Nó không được đề cập trong thông số kỹ thuật là hành vi của nó, vì vậy bạn chỉ có thể dựa vào những gì được viết trong tài liệu Weld.


11
Đo không phải sự thật. Có chú thích javax.inject.Singleton. Nó là một phần của CDI. Kiểm tra tại đây: docs.jboss.org/weld/reference/1.0.1-Final/en-US/html_single/…
amorfis

5
@amorphis - Tôi có thông số CDI trước mặt. Tôi thậm chí đã thực hiện các phần của nó, và nó không đề cập đến bất cứ điều gì @Singleton. Nó chỉ được hiển thị trong một ví dụ, không giải thích rõ. Đúng là CDI dựa vào javax.inject, nhưng nói đúng ra thì nó không phải là một phần của thông số CDI. Điều đó nói rằng, tôi đã sửa lại câu trả lời của mình một chút.
Bozho

17

Tóm lại: Bạn thậm chí có thể kết hợp nó ( @Singleton@ApplicationScoped) và nó có ý nghĩa trong một số trường hợp. (và hoạt động như mong đợi ở tôi!)

Ngoài các câu trả lời khác cho đến nay, tôi muốn bổ sung thêm một số điểm để làm rõ trong các tình huống thế giới thực.

Đối với tôi, câu hỏi này được phát triển từ Làm cách nào để buộc một bean trong phạm vi ứng dụng khởi tạo khi khởi động ứng dụng? Trong một số cuộc thảo luận ở đó, tôi đã nêu điều này và không thể tìm thấy một lập luận hợp lệ nào chống lại nó cho đến nay:

Trong rất nhiều kịch bản / thiết lập thực tế, tôi sẽ nói rằng thật khó để nói chắc chắn - từ quan điểm trừu tượng / mô hình hóa - liệu một cái gì đó (hoặc sẽ trở thành / được đối xử như) một EJB hay một hạt đậu được quản lý trong phạm vi ứng dụng.

Các lập luận (có thể tranh luận nhưng không kết luận) (theo quan điểm của tôi) chống lại nó cho đến nay: (@BalusC và tất cả những người khác: Tôi muốn thấy họ đưa ra kết luận, nhưng nếu không, những điều trên có thể đúng và tuy nhiên các lập luận có thể vẫn giúp người đọc nhận ra sự khác biệt / thuận lợi / khó khăn / xấu / tốt)

EJB so với Managed Bean

BalusC : Đó là một EJB không phải là một bean được quản lý, điều này hoàn toàn khác. Các EJB chạy trong chương trình phụ trợ và các bean được quản lý trong giao diện người dùng. EJB cũng chạy trong ngữ cảnh giao dịch. [...] Bạn vừa nhầm lẫn giữa đậu doanh nghiệp với đậu được quản lý và tôi chỉ ra điều đó.

nhưng:

tôi : Tôi nghĩ rằng bạn không hoàn toàn chính xác và nói quá về ý nghĩa / cách sử dụng và nó có vẻ gây tranh cãi với tôi. http://en.wikipedia.org/wiki/Enterprise_JavaBeans

Enterprise JavaBeans (EJB) là một phần mềm máy chủ được quản lý để xây dựng mô-đun phần mềm doanh nghiệp và là một trong một số API Java. EJB là một thành phần phần mềm phía máy chủ đóng gói logic nghiệp vụ của một ứng dụng.

Các loại Đậu Doanh nghiệp

Đậu phiên [3] có thể là "Trạng thái", "Không trạng thái" hoặc "Singleton" [...]

Message Driven Beans [...]

... mà vẫn đúng trong trường hợp của tôi.

Singleton EJB so với Đậu phạm vi ứng dụng

Khóa

BalusC : Một EJB singleton không giống như một bean phạm vi ứng dụng. Một EJB đơn bị khóa đọc / ghi và do đó có khả năng không hiệu quả / được thay thế quá mức cho nhiệm vụ bạn đã nghĩ đến. Câu chuyện ngắn: Lấy một cuốn sách Java EE hay và học cách sử dụng công cụ phù hợp cho công việc. Một cách chắc chắn không phải là cách khác. Rằng nó hoạt động không có nghĩa là nó là công cụ phù hợp. Một chiếc búa tạ có khả năng vặn ốc vít, nhưng nó không nhất thiết phải là công cụ phù hợp để làm điều đó :)

nhưng:

(Tôi không thể nhìn thấy cái búa tạ ở đây - xin lỗi ...) Thật tốt khi biết các mặc định khóa (tôi không biết về nó), nhưng điều này có vẻ lại không chính xác: Oracle Java EE 6 Hướng dẫn về Quản lý Truy cập Đồng thời trong một Đậu phiên Singleton

Khi tạo một bean phiên singleton, quyền truy cập đồng thời vào các phương thức nghiệp vụ của singleton có thể được kiểm soát theo hai cách: đồng thời được quản lý bởi vùng chứa và đồng thời do bean quản lý. [...]

Mặc dù theo mặc định, các singlet sử dụng đồng thời do vùng chứa quản lý, chú thích @ConcurrencyManagement (CONTAINER) có thể được thêm vào ở cấp lớp của singleton để thiết lập rõ ràng loại quản lý đồng thời


Weld không thích thú khi trộn: Ngoại lệ khi tải ứng dụng: Lỗi định nghĩa CDI: WELD-000046: Có thể chỉ định nhiều nhất một phạm vi trên [EnhancedAnnotatedTypeImpl] public ApplicationScoped Singleton MyClass. Sử dụng javax.inject.Singleton.
sgflt

10

Thông thường, khi bạn muốn chỉ có một phiên bản của đối tượng nào đó, bạn có thể nên sử dụng @ApplicationScopedchú thích - đối tượng đó được proxied và do đó thậm chí có thể được tuần tự hóa đúng cách.

Mặt khác, cũng có nhiều trường hợp, trong đó bạn chỉ muốn một thể hiện của lớp, nhưng lớp đó không thể được proxied (ví dụ vì là cuối cùng) - thì đó @Singletonlà một giải pháp. Bởi vì Singletonlà một phạm vi giả và không được hỗ trợ như bất kỳ phạm vi "bình thường" nào.


Tôi phản đối điều này vì nó rất không rõ ràng. Tôi đã viết mã trong Java EE trong 5 năm, tham gia các bài hướng dẫn và đọc sách, nhưng tôi không hiểu rõ ý bạn là gì khi bạn nói "đối tượng như vậy là proxied", "thậm chí có thể được đăng nhiều kỳ" và "pseudo- phạm vi". Tôi rất muốn biết điều này có nghĩa là gì, vì có vẻ như bạn biết mình đang nói gì, nhưng vì nó được viết ra, tôi không thể tưởng tượng câu trả lời của bạn sẽ giúp ích cho hầu hết các nhà phát triển Java EE.
DavidS

2
Điều đó nói rằng, tôi biết EJBs là proxied. Sự nhầm lẫn của tôi là một phần xung quanh sự khác biệt mà bạn đang tạo ra cho Singletons.
DavidS

9

@Singletontrong JSR-299 đề cập đến các bean phiên Singleton ( javax.ejb.Singleton, không phải javax.inject.Singleton), không phải các bean được quản lý JSR-299 trong phạm vi tích hợp được gọi là Singleton.

Bạn có thể tìm thấy trong máy chủ của mình @ApplicationScopedlà một cho mỗi EAR hoặc một cho mỗi WAR / EJB-JAR vì nó không rõ ràng trong thông số kỹ thuật, nhưng bạn chắc chắn không nên mong đợi nó là một cho mỗi JVM.


7

Có một sự khác biệt nữa: @Singletonkhông phải là bean xác định các chú thích, vì Singletonphạm vi không phải là phạm vi bình thường. Sau đó @ApplicationScopedlà bean xác định các chú thích.

Với thông số kỹ thuật CDI 1.1: Khi ứng dụng ở chế độ khám phá = annotated, Weld không xác định đậu với @Singletonvà không tải ứng dụng này


2

Một trong những điểm khác biệt chính mà bạn có thể viết lớp của mình với hàm tạo mặc định có công cụ sửa đổi quyền truy cập riêng khi sử dụng javax.inject.Singleton, nhưng lớp của bạn phải có hàm tạo mặc định với ít nhất là công cụ sửa đổi truy cập mặc định khi sử dụng javax.enterprise.context.ApplicationScopedvà đây là cách JBOSS 6.1 GA Finaltriển khai


Ý bạn là "hàm tạo mặc định"?
Treefish Zhang
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.