ฉันควรใช้ @EJB หรือ @Inject


148

ฉันพบคำถามนี้: @Inject กับ @EJB แตกต่างกันอย่างไรแต่ฉันไม่ได้ฉลาดกว่านี้ ฉันยังไม่เคยทำ Java EE มาก่อนและฉันไม่เคยมีประสบการณ์ในการฉีดวัคซีนดังนั้นฉันไม่เข้าใจว่าควรใช้อะไรดี?

@EJB เป็นวิธีการฉีดแบบเก่าหรือไม่ การฉีดจะทำโดยคอนเทนเนอร์ EJB เมื่อใช้คำอธิบายประกอบนี้ในขณะที่ใช้ @Inject ใช้กรอบงาน CDI ใหม่หรือไม่ นั่นคือความแตกต่างและฉันควรใช้ @Inject แทนที่จะเป็น @EJB หรือไม่ในกรณีนี้

คำตอบ:


178

@EJBจะใช้ในการฉีด EJB เท่านั้นและสามารถใช้ได้สำหรับค่อนข้างบางเวลาขณะนี้ @Injectสามารถฉีด bean ที่ถูกจัดการใด ๆ และเป็นส่วนหนึ่งของข้อมูลจำเพาะ CDI ใหม่ (ตั้งแต่ Java EE 6)

ในกรณีที่เรียบง่ายคุณก็สามารถเปลี่ยนไป@EJB @Injectในกรณีที่สูงขึ้น (เช่นเมื่อคุณหนักขึ้นอยู่กับ@EJBคุณลักษณะของชอบbeanName, lookupหรือbeanInterfaceกว่า) เพื่อที่จะใช้@Injectคุณจะต้องกำหนด@Producerเขตข้อมูลหรือวิธีการ

ทรัพยากรเหล่านี้อาจจะเป็นประโยชน์ที่จะเข้าใจความแตกต่างระหว่าง@EJBและ@Producesและวิธีการที่จะได้รับสิ่งที่ดีที่สุดของพวกเขา

บล็อกของ Antonio Goncalves:
CDI Part I
CDI Part II
CDI Part III

เอกสาร JBoss Weld:
CDI และระบบนิเวศ Java EE

StackOverflow:
Inject @EJB bean ตามเงื่อนไข


4
ทำไม@EJBการฉีดแบบวงกลม (ถั่วซิงเกิลตันหนึ่งและถั่วอื่นต้องการการอ้างอิงถึงกันและกัน) (มีการอ้างอิงถึงคำตอบของฉันด้านล่าง - ฉันไม่แน่ใจว่าฉันกำลังทำสิ่งที่ถูกต้องโดยเปลี่ยนไปใช้@EJB)
หมอผี

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

33

@Injectสามารถฉีดถั่วใดก็ได้ในขณะที่@EJBสามารถฉีด EJB ได้เท่านั้น คุณสามารถใช้เพื่อฉีด EJB แต่ฉันต้องการได้@Injectทุกที่


1
อะไรที่ทำให้ฉีดเมื่อเราใช้ @Inject ที่เก็บ JavaEE? มันสามารถฉีด POJO ได้หรือไม่?
Koray Tugay

3
ด้วย CDI เป็นภาชนะ CDI (รวมอยู่ในภาชนะ JavaEE)
Bozho

16

อัปเดต:คำตอบนี้อาจไม่ถูกต้องหรือล้าสมัย โปรดดูความคิดเห็นเพื่อดูรายละเอียด

ผมเปลี่ยนจาก@Injectไป@EJBเพราะ@EJBช่วยให้การฉีดวงกลมขณะ@Injectpukes กับมัน

รายละเอียด: ฉันต้องการ@PostConstructเรียก@Asynchronousวิธี แต่มันจะทำแบบซิงโครนัส วิธีเดียวที่จะทำการโทรแบบอะซิงโครนัสได้คือให้การโทรแบบเดิมเป็นวิธีการของถั่วอื่นและให้มันโทรกลับวิธีการของถั่วเดิม ในการทำสิ่งนี้ถั่วแต่ละตัวจำเป็นต้องมีการอ้างอิงถึงอันอื่น - จึงเป็นวงกลม @Injectล้มเหลวสำหรับงานนี้ในขณะที่@EJBทำงาน


@MartijnBurger ฉันไม่มีรหัสที่มีประโยชน์หรือสภาพแวดล้อม Java EE มีประโยชน์ เพียงแค่สร้าง 2 Java คลาสและ@Injectพวกเขาลงในเขตข้อมูลสาธารณะของกันและกัน หากใช้งานได้คำตอบของฉันก็ผิด หากวิธีนี้ใช้ไม่ได้ผลคำตอบของฉันก็ถูกต้องแล้ว การเปลี่ยนแปลงต่อไป@Injectที่จะ@EJB(และอาจจะใส่คำอธิบายประกอบการเรียนของตัวเองหรือไม่ฉันลืม.) จากนั้นการฉีดยาร่วมกันแบบวัฏจักรควรจะทำงานได้ดี นั่นเป็นเหตุผลที่ผมเปลี่ยนจากการ@Inject @EJBหวังว่ามันจะสมเหตุสมผล
หมอผี

ฉันสร้างสอง pojo แล้วฉีดของ pojo เข้าด้วยกัน ทำงานได้โดยไม่มีปัญหาในการตั้งค่าของฉัน (WildFly 8.2 = CDI 1.2)
Martijn Burger

1
ขอบคุณ @MartijnBurger ฉันจะยืนยันอย่างนั้นและในขณะเดียวกันก็เพิ่มความระมัดระวังให้กับคำตอบของฉัน
หมอผี

ไม่แน่ใจว่าสิ่งที่คุณต้องการที่จะบรรลุ แต่อาจทำสิ่งที่คุณต้องการและไม่มีการพึ่งพาแบบวงกลม tomee.apache.org/examples-trunk/async-postconstruct/README.html เหตุการณ์ CDI แบบอะซิงโครนัสอาจเป็นวิธีที่สะอาดกว่า (ขึ้นอยู่กับข้อกำหนด)
JanM

12

นี่คือการอภิปรายที่ดีในหัวข้อ Gavin King แนะนำ @Inject เหนือ @EJB สำหรับ EJB ที่ไม่ใช่ระยะไกล

http://www.seamframework.org/107780.lace

หรือ

https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace

เรื่องการฉีดด้วย @EJB หรือ @Inject?

  1. พ.ย. 2009, 20:48 อเมริกา / New_York | Link กาวินคิง

ข้อผิดพลาดนั้นแปลกมากเนื่องจากการอ้างอิงในท้องถิ่นของ EJB นั้นควรจะเป็นอนุกรม ข้อผิดพลาดใน glassfish อาจ?

โดยทั่วไป @Inject จะดีกว่าเสมอเนื่องจาก:

it is more typesafe,
it supports @Alternatives, and
it is aware of the scope of the injected object.

ฉันไม่แนะนำให้ใช้ @EJB ยกเว้นการประกาศการอ้างอิงถึง EJB ระยะไกล

และ

เรื่องการฉีดด้วย @EJB หรือ @Inject?

  1. พ.ย. 2009, 17:42 อเมริกา / New_York | Link กาวินคิง

    มันหมายถึง @EJB ดีกว่าด้วย EJB ระยะไกลหรือไม่

สำหรับ EJB ระยะไกลเราไม่สามารถประกาศข้อมูลเมตาเช่น qualifier, @Alternative, และอื่น ๆ ในคลาส bean เนื่องจากไคลเอนต์ไม่สามารถเข้าถึงข้อมูลเมตานั้นได้ นอกจากนี้ยังต้องระบุข้อมูลเมตาเพิ่มเติมบางส่วนซึ่งเราไม่ต้องการสำหรับกรณีท้องถิ่น (ชื่อ JNDI ทั่วโลกของอะไรก็ตาม) ดังนั้นทุกสิ่งที่ต้องไปที่อื่น: คือการประกาศ @Produces


1
ในขณะที่สิ่งนี้อาจตอบคำถามในทางทฤษฎีมันก็ควรจะรวมส่วนสำคัญของคำตอบที่นี่และให้ลิงค์สำหรับการอ้างอิง ด้วยวิธีนี้คำตอบนี้จะมีค่าแม้ตอนนี้ลิงก์จะตาย
Mifeet


4

อาจเป็นประโยชน์ในการทำความเข้าใจความแตกต่างในแง่ของ Session Bean Identity เมื่อใช้ @EJB และ @Inject ตามข้อกำหนดคุณสมบัติรหัสต่อไปนี้จะเป็นtrue:

@EJB Cart cart1;
@EJB Cart cart2;
 if (cart1.equals(cart2)) { // this test must return true ...}

การใช้ @Inject แทน @EJB นั้นไม่เหมือนกัน

ดูที่เซสชันเอกลักษณ์ถั่วไร้สัญชาติสำหรับข้อมูลเพิ่มเติม


0

การฉีดมีอยู่แล้วใน Java EE 5 ด้วยคำอธิบายประกอบ @Resource, @PersistentUnit หรือ @EJB เป็นต้น แต่มันถูก จำกัด ไว้ที่ทรัพยากรบางอย่าง (แหล่งข้อมูล, EJB...) และเป็นส่วนประกอบบางอย่าง (Servlets, EJB, JSF สำรองถั่ว..) ด้วย CDI คุณสามารถฉีดได้เกือบทุกที่ด้วยคำอธิบายประกอบ @Inject

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