อะไรคือความแตกต่างระหว่าง @ApplicationScoped และ @Singleton Scopes ใน CDI


96

ใน CDI มีขอบเขตหลอก@ApplicationScopedและ ( javax.inject) @Singletonอะไรคือความแตกต่างระหว่างพวกเขา? นอกเหนือจากข้อเท็จจริงที่เป็นผู้รับ@ApplicationScopedมอบฉันทะและ@Singletonไม่ใช่

ฉันสามารถเปลี่ยน@Singletonถั่วเป็น@ApplicationScoped? สามารถ@ApplicationScopedถั่วมีสอง (หรือมากกว่า) กรณี?


12
คุณได้อ่านข้อมูลอ้างอิงของ Weldหรือไม่? มีคำอธิบายบางประการเกี่ยวกับความแตกต่างในทางปฏิบัติระหว่าง@ApplicationScopedและ@Singletonในมาตรา 5.4 (น. 36)
brandizzi

1
คุณกำลังอ้างถึงขอบเขต Singleton ใด - javax.ejb หรือ javax.inject
John Ament

คำตอบ:


30

@Singletonไม่ได้เป็นส่วนหนึ่งของข้อกำหนด CDI เป็นส่วนหนึ่งของ EJB และjavax.inject(JSR-330) ไม่มีการกล่าวถึงในข้อมูลจำเพาะว่าพฤติกรรมของมันคืออะไรดังนั้นคุณสามารถพึ่งพาสิ่งที่เขียนไว้ในเอกสาร Weld เท่านั้น


11
ที่ไม่เป็นความจริง. มีคำอธิบายประกอบ javax.inject.Singleton เป็นส่วนหนึ่งของ CDI ตรวจสอบที่นี่: docs.jboss.org/weld/reference/1.0.1-Final/en-US/html_single/…
amorfis

5
@amorphis - ฉันมีข้อมูลจำเพาะของ CDI อยู่ข้างหน้าฉัน ฉันได้ดำเนินการบางส่วนแล้วและไม่ได้กล่าวถึงอะไร@Singletonเลย แสดงเป็นเพียงตัวอย่างเดียวโดยไม่มีการชี้แจง เป็นเรื่องจริงที่ CDI ต้องอาศัยjavax.injectแต่การพูดอย่างเคร่งครัดไม่ใช่ส่วนหนึ่งของข้อมูลจำเพาะของ CDI ที่กล่าวว่าฉันแก้ไขคำตอบของฉันเล็กน้อย
Bozho

17

ในระยะสั้น: คุณสามารถผสม ( @Singletonและ@ApplicationScoped) ได้และมันก็สมเหตุสมผลในบางสถานการณ์ (และทำงานได้ตามที่ฉันคาดไว้!)

นอกจากนี้สำหรับคำตอบอื่น ๆ จนถึงตอนนี้ฉันต้องการเพิ่มประเด็นอื่น ๆ เพื่อความกระจ่างในสถานการณ์จริง

สำหรับฉันคำถามนี้พัฒนามาจากฉันจะบังคับให้แอปพลิเคชันที่กำหนดขอบเขต bean อินสแตนซ์เมื่อเริ่มต้นแอปพลิเคชันได้อย่างไร ในการสนทนาบางครั้งฉันได้กล่าวถึงสิ่งนี้และไม่สามารถหาข้อโต้แย้งที่ถูกต้องได้:

ในสถานการณ์ / การตั้งค่าในชีวิตจริงจำนวนมากฉันจะบอกว่ามันยากที่จะพูดอย่างแน่นอน - จากมุมมองที่เป็นนามธรรม / การสร้างแบบจำลอง - ไม่ว่าบางสิ่งจะเป็น (หรือจะกลายเป็น / ได้รับการปฏิบัติเช่นใด) EJB หรือถั่วที่มีการจัดการขอบเขตแอปพลิเคชัน

(เป็นที่ถกเถียงกัน แต่ไม่สามารถสรุปได้) ข้อโต้แย้ง (จากมุมมองของฉัน) กับมันจนถึงตอนนี้: (@BalusC และคนอื่น ๆ ทั้งหมด: ฉันอยากเห็นพวกเขาสรุปได้ แต่ถ้าไม่เป็นเช่นนั้นข้างต้นอาจเป็นจริงและอย่างไรก็ตามข้อโต้แย้งอาจ ยังคงช่วยให้ผู้อ่านได้รับความแตกต่าง / ข้อดี / ข้อเสีย / ไม่ดี / แนวทางปฏิบัติที่ดี)

EJB กับ Managed Bean

BalusC : นั่นคือ EJB ไม่ใช่ถั่วที่มีการจัดการซึ่งแตกต่างกันมาก EJB ทำงานในแบ็กเอนด์และถั่วที่มีการจัดการในส่วนหน้า EJB ทำงานในบริบทการทำธุรกรรมด้วย [... ] คุณเพิ่งสับสนถั่วขององค์กรกับถั่วที่มีการจัดการและฉันก็ชี้ให้เห็นว่า

แต่:

ฉัน : ฉันคิดว่าคุณไม่ค่อยถูกต้องนักและพูดเกินจริงในความหมาย / การใช้งานและมันก็ดูเป็นที่ถกเถียงกันสำหรับฉัน http://en.wikipedia.org/wiki/Enterprise_JavaBeans

Enterprise JavaBeans (EJB) เป็นซอฟต์แวร์เซิร์ฟเวอร์ที่มีการจัดการสำหรับการสร้างซอฟต์แวร์องค์กรแบบแยกส่วนและเป็นหนึ่งใน Java API หลายตัว EJB เป็นส่วนประกอบซอฟต์แวร์ฝั่งเซิร์ฟเวอร์ที่สรุปตรรกะทางธุรกิจของแอปพลิเคชัน

ประเภทของ Enterprise Beans

ถั่วเซสชัน [3] ที่สามารถเป็นได้ทั้งแบบ "Stateful", "Stateless" หรือ "Singleton" [... ]

ถั่วขับเคลื่อนข้อความ [... ]

... ซึ่งยังคงเป็นจริงในกรณีของฉัน

Singleton EJB เทียบกับ Application Scoped Bean

การล็อค

BalusC : Singleton EJB ไม่เหมือนกับแอปพลิเคชันที่กำหนดขอบเขตถั่ว Singleton EJB ถูกล็อคและอาจไม่มีประสิทธิภาพ / ซับซ้อนเกินไปสำหรับงานที่คุณคิดไว้ เรื่องสั้น: หยิบหนังสือ Java EE ดีๆสักเล่มและเรียนรู้การใช้เครื่องมือที่เหมาะสมกับงาน วิธีหนึ่งไม่ใช่วิธีอื่นแน่นอน มันได้ผลไม่ได้หมายความว่าเป็นเครื่องมือที่เหมาะสม ค้อนขนาดใหญ่สามารถขันสกรูได้ แต่ก็ไม่จำเป็นต้องเป็นเครื่องมือที่เหมาะสม :)

แต่:

(ฉันไม่เห็นค้อนขนาดใหญ่ที่นี่ - ขออภัย ... ) เป็นเรื่องดีที่ทราบค่าเริ่มต้นการล็อก (ฉันไม่รู้) แต่ดูเหมือนว่าจะไม่ถูกต้องอีกครั้ง: บทช่วยสอน Oracle Java EE 6เกี่ยวกับการจัดการการเข้าถึงพร้อมกันใน a Singleton Session Bean

เมื่อสร้างเซสชัน bean แบบซิงเกิลตันการเข้าถึงวิธีการทางธุรกิจของ singleton พร้อมกันสามารถควบคุมได้สองวิธี: การจัดการพร้อมกันด้วยคอนเทนเนอร์และการจัดการพร้อมกันของ bean [... ]

แม้ว่าโดยค่าเริ่มต้น singletons จะใช้ container-management concurrency แต่คำอธิบายประกอบ @ConcurrencyManagement (CONTAINER) อาจถูกเพิ่มที่ระดับคลาสของซิงเกิลตันเพื่อตั้งค่าประเภทการจัดการพร้อมกันอย่างชัดเจน


Weld ไม่น่าขบขันโดยการผสม: ข้อยกเว้นขณะโหลดแอป: ความล้มเหลวของข้อกำหนด CDI: WELD-000046: สามารถระบุขอบเขตได้มากที่สุดใน [EnhancedAnnotatedTypeImpl] Public ApplicationScoped Singleton MyClass ใช้ javax.inject.Singleton
sgflt

12

โดยปกติแล้วเมื่อคุณต้องการมีเพียงอินสแตนซ์ของอ็อบเจ็กต์บางตัวคุณอาจควรใช้@ApplicationScopedคำอธิบายประกอบ - อ็อบเจ็กต์ดังกล่าวเป็นพร็อกซีดังนั้นจึงสามารถต่ออนุกรมได้อย่างถูกต้องเมื่อไม่อยู่ในกรอบ

ในทางกลับกันยังมีอีกหลายกรณีที่คุณต้องการเพียงอินสแตนซ์เดียวของคลาส แต่คลาสดังกล่าวไม่สามารถพร็อกซีได้ (เช่นเนื่องจากเป็นขั้นสุดท้าย) - จากนั้น@Singletonเป็นการช่วยเหลือ เนื่องจากSingletonเป็นขอบเขตหลอกและไม่ได้รับการมอบฉันทะเหมือนกับขอบเขต "ปกติ" ใด ๆ


ฉันลงคะแนนเรื่องนี้เพราะมันไม่ชัดเจนมาก ฉันเขียนโค้ดใน Java EE เป็นเวลาห้าปีรับบทแนะนำและอ่านหนังสือ แต่ฉันไม่รู้ชัดเจนว่าคุณหมายถึงอะไรเมื่อคุณพูดว่า "วัตถุดังกล่าวเป็นพร็อกซี" "สามารถต่ออนุกรมได้อย่างถูกต้อง" และ "หลอก - ขอบเขต". ฉันชอบที่จะรู้ความหมายของสิ่งนี้เนื่องจากดูเหมือนว่าคุณจะรู้ว่าคุณกำลังพูดถึงอะไร แต่ตามที่เขียนไว้ฉันนึกไม่ออกว่าคำตอบของคุณจะช่วยนักพัฒนา Java EE ส่วนใหญ่ได้
DavidS

2
ที่กล่าวว่าฉันรู้ว่า EJB เป็นพร็อกซี ความสับสนของฉันบางส่วนเกี่ยวกับความแตกต่างที่คุณสร้างขึ้นสำหรับ Singletons
DavidS

9

@Singletonใน JSR-299 หมายถึงถั่วเซสชัน Singleton ( javax.ejb.Singletonไม่ใช่javax.inject.Singleton) ไม่ใช่ถั่วที่มีการจัดการ JSR-299 ในขอบเขตในตัวที่เรียกว่า Singleton

คุณอาจพบในเซิร์ฟเวอร์ของคุณที่@ApplicationScopedเป็นหนึ่งต่อ EAR หรือหนึ่งต่อหนึ่ง WAR / EJB-JAR เนื่องจากไม่ชัดเจนในข้อกำหนด แต่คุณไม่ควรคาดหวังว่าจะเป็นหนึ่งต่อหนึ่ง JVM


7

มีข้อแตกต่างอีกประการหนึ่ง: @Singletonไม่ใช่การกำหนดคำอธิบายประกอบแบบ bean เนื่องจากSingletonขอบเขตไม่ใช่ขอบเขตปกติ จากนั้น@ApplicationScopedเป็นคำอธิบายประกอบที่กำหนดถั่ว

ด้วยข้อมูลจำเพาะ CDI 1.1: เมื่อแอปพลิเคชันในโหมดการค้นพบ = มีคำอธิบายประกอบ Weld จะไม่ระบุถั่วด้วย@Singletonและไม่ได้โหลดสิ่งนี้


2

ความแตกต่างที่สำคัญประการหนึ่งที่คุณสามารถเขียนคลาสของคุณด้วยตัวสร้างเริ่มต้นมีตัวแก้ไขการเข้าถึงส่วนตัวเมื่อใช้javax.inject.Singletonงาน แต่คลาสของคุณควรมีตัวสร้างเริ่มต้นที่มีตัวแก้ไขการเข้าถึงเริ่มต้นอย่างน้อยเมื่อใช้javax.enterprise.context.ApplicationScopedและนี่คือJBOSS 6.1 GA Finalการใช้งาน


คุณหมายถึง“ ตัวสร้างเริ่มต้น” ใช่หรือไม่
Treefish Zhang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.