CDI และ EJB เปรียบเทียบได้อย่างไร? โต้ตอบ?


106

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

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

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


3
คำถามนี้ติดอันดับต้น ๆ ในการค้นหา "EJB CDI difference" ของ Google แต่ฉันพบคำตอบที่stackoverflow.com/questions/13487987/…ชัดเจนกว่า
matt freake

คำตอบ:


50

CDI:มันเกี่ยวกับการฉีดแบบพึ่งพา หมายความว่าคุณสามารถแทรกการใช้งานอินเทอร์เฟซได้ทุกที่ วัตถุนี้สามารถเป็นอะไรก็ได้ไม่สามารถเกี่ยวข้องกับ EJB นี่คือตัวอย่างวิธีการฉีดเครื่องกำเนิดไฟฟ้าแบบสุ่มโดยใช้ CDI ไม่มีอะไรเกี่ยวกับ EJB คุณจะใช้ CDI เมื่อคุณต้องการฉีดบริการที่ไม่ใช่ EJB การใช้งานหรืออัลกอริทึมที่แตกต่างกัน (ดังนั้นคุณไม่จำเป็นต้องใช้ EJB ที่นั่นเลย)
EJB:คุณเข้าใจและอาจสับสนกับ@EJBคำอธิบายประกอบ - ช่วยให้คุณสามารถใช้งานในบริการของคุณหรืออะไรก็ได้ แนวคิดหลักคือคลาสที่คุณฉีดควรได้รับการจัดการโดย EJB container ดูเหมือนว่า CDI จะเข้าใจว่า EJB คืออะไรดังนั้นในเซิร์ฟเวอร์ที่รองรับ Java EE 6 ใน servlet ของคุณคุณสามารถเขียนทั้งสองอย่างได้

@EJB EJBService ejbService;

และ

@Inject EJBService ejbService;

นั่นคือสิ่งที่ทำให้คุณสับสน แต่นั่นอาจเป็นเพียงสิ่งเดียวที่เป็นสะพานเชื่อมระหว่าง EJB และ CDI

เมื่อเรากำลังพูดถึง CDI คุณสามารถแทรกอ็อบเจ็กต์อื่น ๆ ลงในคลาสที่มีการจัดการ CDI ได้ (ควรสร้างโดย CDI awareness frameworks)

CDI เสนออะไรอีกบ้าง ... ตัวอย่างเช่นคุณใช้ Struts 2 เป็นเฟรมเวิร์ก MVC (ตัวอย่าง) และคุณถูก จำกัด ที่นี่แม้ใช้ EJB 3.1 - คุณไม่สามารถใช้@EJBคำอธิบายประกอบในการดำเนินการ Struts แต่ก็ไม่ได้รับการจัดการโดยคอนเทนเนอร์ แต่เมื่อคุณเพิ่มปลั๊กอิน Struts2-CDI คุณสามารถเขียน@Injectคำอธิบายประกอบสำหรับสิ่งเดียวกันได้ (จึงไม่จำเป็นต้องค้นหา JNDI อีกต่อไป) วิธีนี้จะช่วยเพิ่มพลัง EJB แต่อย่างที่ฉันได้กล่าวไว้ก่อนหน้านี้สิ่งที่คุณฉีดด้วย CDI - ไม่สำคัญว่ามันจะเกี่ยวข้องกับ EJB หรือไม่และนั่นคือพลังของมัน

ปล. อัปเดตลิงก์ไปยังตัวอย่าง


@EJB และ @Inject มีฟังก์ชันเทียบเท่ากันหรือไม่? ฉันคิดว่ามันเป็นวิธีการฉีดที่ทับซ้อนกันระหว่าง CDI กับส่วนที่เหลือของซุปตัวย่อ Java EE ที่ทำให้ฉันสับสน การอ่านเพิ่มเติมดูเหมือนจะบ่งชี้ว่ามีความหวังที่จะจัดแนวคำอธิบายประกอบ
ทิม

@Maxym เมื่อคุณใช้ @ Inject คุณจะมั่นใจได้อย่างไรว่า @ Stateless หรือคอมโพเนนต์ด้านเซิร์ฟเวอร์อื่น ๆ ของ EJB ยังคงใช้คุณสมบัติเช่นการรวมหรือการทำงานพร้อมกันที่คอนเทนเนอร์นำเสนอ ฉันหวังว่าสิ่งนี้จะไม่ถูกนำเสนอโดย CDI ใช่ไหม
Bala

1
@Bala: CDI ไม่มีการรวม ... ดูที่CDI มีหรือไม่มี EJB3.1หวังว่าจะตอบคำถามของคุณ ..
Maxym

@KorayTugay: CDI เป็นคุณสมบัติ Java EE ดังนั้นเซิร์ฟเวอร์ที่รองรับ Java EE 6 ใด ๆ ก็มีได้ (ไม่ผิดพลาด Glassfish 3.0.1+, JBoss 6+ เป็นต้น) คุณสามารถดู JBoss Weld ซึ่งเป็นการนำ CDI อ้างอิงไปใช้ สามารถใช้เช่น Tomcat ...
Maxym

191

ขณะนี้ค่อนข้างสับสนเนื่องจากขณะนี้มีโมเดลส่วนประกอบหลายตัวใน Java EE พวกเขาเป็นCDI , EJB3และJSF Managed ถั่ว

CDIเป็นเด็กใหม่ในบล็อก ถั่ว CDI มีdependency injection, และscoping event busถั่ว CDI มีความยืดหยุ่นมากที่สุดเมื่อเทียบกับการฉีดและการกำหนดขอบเขต รถบัสเหตุการณ์มีน้ำหนักเบามากและเหมาะอย่างยิ่งสำหรับการใช้งานเว็บที่ง่ายที่สุด นอกจากนี้ CDI ยังมีคุณลักษณะขั้นสูงที่เรียกว่าportable extensionsซึ่งเป็นกลไกปลั๊กอินสำหรับผู้ขายเพื่อให้ฟังก์ชันพิเศษแก่ Java EE ซึ่งสามารถใช้ได้กับการใช้งานทั้งหมด (Glassfish, JBoss AS, Websphere ฯลฯ ) .

ถั่วEJB3ได้รับการติดตั้งเพิ่มเติมจากโมเดลส่วนประกอบ EJB2 ดั้งเดิม*และเป็นถั่วแรกใน Java EE ที่ได้รับการจัดการถั่วผ่านคำอธิบายประกอบ ถั่ว EJB3 มีdependency injection, declarative transactions, declarative security, pooling, concurrency control, และasynchronous executionremoting

การฉีดแบบพึ่งพาในถั่ว EJB3 นั้นไม่ยืดหยุ่นเหมือนในถั่ว CDI และถั่ว EJB3 ไม่มีแนวคิดในการกำหนดขอบเขต อย่างไรก็ตามถั่ว EJB3 เป็นแบบธุรกรรมและรวมกันโดยค่าเริ่มต้น**สองสิ่งที่มีประโยชน์มากที่ CDI เลือกที่จะทิ้งไว้ในโดเมนของ EJB3 รายการอื่น ๆ ที่กล่าวถึงยังไม่มีใน CDI แม้ว่า EJB3 จะไม่มีบัสเหตุการณ์เป็นของตัวเอง แต่มันมีถั่วชนิดพิเศษสำหรับฟังข้อความ ถั่วที่ขับเคลื่อนด้วยข้อความ สามารถใช้เพื่อรับข้อความจาก Java Messaging System หรือจากระบบอื่น ๆ ที่มีอะแด็ปเตอร์รีซอร์ส JCA การใช้ข้อความเป่าเต็มรูปแบบสำหรับเหตุการณ์ง่ายๆนั้นมีน้ำหนักมากกว่าบัสเหตุการณ์ CDI และ EJB3 กำหนดเฉพาะผู้ฟังเท่านั้นไม่ใช่ API ผู้ผลิต

JSF Managed Beansมีอยู่ใน Java EE นับตั้งแต่มีการรวม JSF พวกเขามีมากเกินไปและdependency injection scopingJSF Managed Beans นำเสนอแนวคิดของการกำหนดขอบเขตแบบเปิดเผย เดิมขอบเขตค่อนข้าง จำกัด และใน Java EE เวอร์ชันเดียวกันที่สามารถประกาศถั่ว EJB3 ผ่านคำอธิบายประกอบได้แล้ว JSF Managed Beans ยังคงต้องประกาศใน XML ในที่สุด JSF Managed Beans เวอร์ชันปัจจุบันได้รับการประกาศผ่านคำอธิบายประกอบและขอบเขตจะขยายด้วยขอบเขตมุมมองและความสามารถในการสร้างขอบเขตที่กำหนดเอง ขอบเขตมุมมองซึ่งจดจำข้อมูลระหว่างการร้องขอไปยังเพจเดียวกันเป็นคุณลักษณะเฉพาะของ JSF Managed Beans

นอกเหนือจากขอบเขตมุมมองแล้วยังมี JSF Managed Beans ใน Java EE 6 น้อยมากขอบเขตมุมมองที่ขาดหายไปใน CDI นั้นโชคไม่ดีเนื่องจาก CDI จะเป็นชุดที่สมบูรณ์แบบของสิ่งที่ JSF Managed Beans นำเสนอ อัปเดต : ใน Java EE 7 / JSF 2.2 มีการเพิ่ม@ViewScoped ที่เข้ากันได้กับ CDI ทำให้ CDI เป็นชุดสุดยอดที่สมบูรณ์แบบ อัปเดต 2 : ใน JSF2.3 ถั่วที่มีการจัดการ JSF ได้เลิกใช้งานแล้วเพื่อสนับสนุนถั่วที่มีการจัดการ CDI

ด้วย EJB3 และ CDI สถานการณ์จะไม่ชัดเจนนัก โมเดลส่วนประกอบ EJB3 และ API มีบริการมากมายที่ CDI ไม่มีให้ดังนั้นโดยทั่วไปแล้ว EJB3 จึงไม่สามารถแทนที่ด้วย CDI ได้ ในทางกลับกัน CDI สามารถใช้ร่วมกับ EJB3 ได้เช่นเพิ่มการรองรับขอบเขตให้กับ EJB

Reza Rahman สมาชิกกลุ่มผู้เชี่ยวชาญและผู้ดำเนินการใช้งาน CDI ที่เรียกว่า CanDI ได้บอกใบ้บ่อยครั้งว่าบริการที่เกี่ยวข้องกับโมเดลส่วนประกอบ EJB3 สามารถติดตั้งเพิ่มเติมเป็นชุดคำอธิบายประกอบ CDI ได้ หากเป็นเช่นนั้นถั่วที่จัดการทั้งหมดใน Java EE อาจกลายเป็นถั่ว CDI นี่ไม่ได้หมายความว่า EJB3 หายไปหรือล้าสมัย แต่เพียงแค่นั้นฟังก์ชันการทำงานของมันจะถูกเปิดเผยผ่าน CDI แทนที่จะเป็นคำอธิบายประกอบของ EJB เช่น @Stateless และ @EJB

อัปเดต

David Blevins แห่ง TomEE และชื่อเสียงของ OpenEJB อธิบายความแตกต่างและความคล้ายคลึงกันระหว่าง CDI และ EJB ได้เป็นอย่างดีในบล็อกของเขา: CDI เมื่อใดที่จะแยก EJB

* แม้ว่าจะเป็นเพียงการเพิ่มขึ้นของหมายเลขเวอร์ชัน แต่ถั่ว EJB3 นั้นส่วนใหญ่เป็นชนิดของ bean ที่แตกต่างกันโดยสิ้นเชิง: pojo ธรรมดาที่กลายเป็น "ถั่วที่มีการจัดการ" โดยใช้คำอธิบายประกอบแบบง่าย ๆ เทียบกับแบบจำลองใน EJB2 ที่มีน้ำหนักมากและ ตัวบอกการปรับใช้ XML ที่ละเอียดเกินไปจำเป็นสำหรับแต่ละ bean นอกเหนือจาก bean ที่จำเป็นในการใช้งานที่มีน้ำหนักมากและสำหรับส่วนต่อประสานส่วนประกอบที่ไม่มีความหมายส่วนใหญ่

** โดยทั่วไปเซสชันถั่วที่ไม่มีสถานะจะถูกรวมเข้าด้วยกันโดยทั่วไปแล้วถั่วเซสชันที่มีสถานะจะไม่ได้ (แต่สามารถเป็นได้) สำหรับทั้งสองประเภทการรวมกลุ่มจึงเป็นทางเลือกและข้อมูลจำเพาะ EJB ไม่ได้กำหนดไว้ในทางใดทางหนึ่ง


3
ฉันสับสนเล็กน้อยกับข้อความของคุณที่ว่า "ถั่ว EJB3 ไม่มีแนวคิดในการกำหนดขอบเขต" และ "EJB3 ไม่มีบัสเหตุการณ์เป็นของตัวเอง" สิ่งนี้สอดคล้องกับคำกล่าวอ้างของ David Blevinที่ว่า "EJBs เป็นเมล็ดถั่ว CDI จึงมีประโยชน์ทั้งหมดของ CDI"? มีอะไรเปลี่ยนแปลงไปบ้างในส่วนนี้ระหว่างเวลาที่คุณเขียนคำตอบกับตอนที่ David เขียนรายการ Blog ของเขา?
คริส

5
อาจเป็นเพราะแนวคิดที่ค่อนข้างสับสนว่า จริงๆแล้วไม่มี "ถั่ว CDI" แต่มีบริการที่ใช้กับถั่วที่มีการจัดการ เพื่อประโยชน์ในการอภิปรายผู้คน (และตัวฉันเอง) จึงเรียกพวกเขาว่า "ถั่ว CDI" อย่างไรก็ตามก่อน CDI ถั่ว EJB ไม่มีการกำหนดขอบเขตอย่างชัดเจนดังที่ David อธิบายว่า Stateful มีขอบเขตโดยปริยาย (และไม่มีขอบเขตโดยเฉพาะ) ในตอนนี้ ด้วย CDI ที่มีอยู่ถั่ว EJB สามารถใช้ประโยชน์จากขอบเขตที่จัดเตรียมไว้ของ CDI หากไม่มีข้อมูลจำเพาะของ CDI ดังนั้นเมื่อดูข้อมูลจำเพาะ EJB เพียงอย่างเดียวจึงไม่มีขอบเขตที่ชัดเจน
Arjan Tijms

1
คุณสามารถอธิบายรายละเอียดเกี่ยวกับความหมายของ "มีบริการที่ใช้กับถั่วที่มีการจัดการ" ได้หรือไม่ หมายความว่าไม่มีสิ่งที่เรียกว่า CDI bean จริงหรือ? เป็นเพียงคุณสมบัติพิเศษบางอย่างใน POJO - EJB - หรือ JSF Managed Bean? เช่นเดียวกับความสามารถในการใช้คำอธิบายประกอบ Inject ใน JSF Managed Bean?
Koray Tugay

3
@Chris เพื่อชี้แจงเพิ่มเติมจากมุมมองข้อมูลจำเพาะของ EJB เราได้ทำการตัดสินใจโดยเจตนาตั้งแต่เริ่มต้นของ CDI เพื่อกำหนดให้การใช้งาน EJB ต้องรองรับคุณลักษณะ CDI 100% ที่กำหนดไว้ใน EJB ทุกแง่มุมของ CDI ทำงานบน EJB ยกเว้นขอบเขตที่เราต้อง จำกัด ไว้ที่ Stateful beans เท่านั้น
David Blevins

1
โปรดทราบว่าตอนนี้ JSF 2.2 มี javax.faces.view.ViewScoped ซึ่งเป็นส่วนขยาย CDI ซึ่งโดยพื้นฐานแล้วเป็นพอร์ตของขอบเขตมุมมอง JSF ไปยัง CDI ด้วยเหตุนี้ CDI จึงเป็นการแทนที่แบบเต็มรูปแบบสำหรับ JSF Managed Beans
jdessey

-1

Albert Einstein: If you can't explain it simply, you don't understand it well enough

Ejbs และ CDI ค่อนข้างเข้าใจง่าย

Ejbs:

  1. จะมีการใส่คำอธิบายประกอบโดยขอบเขตคุณสมบัติเสมอเช่น @Stateless, @Stateful, @Request เป็นต้น
  2. อินสแตนซ์ของ Ejbs ถูกควบคุมโดยเฟรมเวิร์ก Java EE และรวมเข้าด้วยกัน เป็นหน้าที่ของ EE framework ในการจัดหาอินสแตนซ์สำหรับผู้บริโภค

@Stateless

 public class CarMaker(){
    public void createCar(Specification specs){
        Car car = new Car(specs);
    }
}

CarMaker มีคำอธิบายประกอบด้วยขอบเขต Ejbs เฉพาะดังนั้นจึงเป็น Ejb

CDI:

  1. ไม่ได้รับการจัดการโดยกรอบงาน EE ทั้งหมดจึงต้องสร้างอินสแตนซ์ด้วยตัวเอง
  2. มันขึ้นอยู่เสมอ ให้ฉันอธิบาย "ขึ้นอยู่กับ" ด้วยตัวอย่าง:

    class Specification { private String color; private String model; //- Getter and Setter }

Specificationชั้น CDI เพราะมันไม่ได้มีคำอธิบายประกอบกับ EJB ขอบเขตและยังนี้ได้เริ่มต้นที่จะตามรหัสของคุณจะไม่กรอบ EE จุดหนึ่งที่น่าสังเกตว่านี่คือเนื่องจากเราไม่ได้มีคำอธิบายประกอบSpecificationชั้นมันเป็นค่าเริ่มต้นข้อเขียนโดย@Dependentคำอธิบายประกอบ

@Dependent  <- By default added 
class Specification { ... }

Further reading: คุณจำเป็นต้องศึกษาเพิ่มเติมระหว่างคำอธิบายประกอบขอบเขต Ejbs และคำอธิบายประกอบขอบเขต CDI ซึ่งจะทำให้แนวคิดนี้ชัดเจนขึ้น


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