Bagaimana CDI dan EJB dibandingkan? berinteraksi?

106

Saya mengalami kesulitan memahami bagaimana keduanya berinteraksi dan di mana batas antara mereka berada. Apakah mereka tumpang tindih? Apakah ada redundansi di antara mereka?

Saya tahu ada anotasi yang terkait dengan keduanya, tetapi saya belum dapat menemukan daftar lengkap untuk keduanya dengan deskripsi singkat. Tidak yakin apakah ini akan membantu menjelaskan perbedaannya atau di mana tumpang tindihnya.

Benar-benar hanya bingung. Saya (rasa saya) memahami EJB dengan cukup baik, saya rasa saya mengalami kesulitan memahami dengan tepat apa yang dibawa CDI ke meja dan bagaimana CDI menggantikan atau meningkatkan apa yang sudah ditawarkan EJB.

Tim
sumber
3
Pertanyaan ini menempati urutan teratas pada pencarian "Perbedaan CDI EJB" Google, tetapi saya menemukan jawabannya di stackoverflow.com/questions/13487987/… lebih jelas
matt freake

Jawaban:

50

CDI: tentang injeksi ketergantungan. Ini berarti Anda dapat memasukkan implementasi antarmuka di mana saja. Objek ini bisa apa saja, tidak bisa terkait dengan EJB. Berikut adalah contoh cara menginjeksi generator acak menggunakan CDI. Tidak ada tentang EJB. Anda akan menggunakan CDI ketika Anda ingin memasukkan layanan non-EJB, implementasi atau algoritma yang berbeda (jadi Anda tidak memerlukan EJB sama sekali).
EJB: Anda benar-benar mengerti, dan mungkin Anda bingung dengan @EJBanotasi - ini memungkinkan Anda untuk memasukkan implementasi ke dalam layanan Anda atau apa pun. Ide utamanya adalah bahwa kelas, tempat Anda menyuntikkan, harus dikelola oleh wadah EJB. Sepertinya CDI mengerti apa itu EJB, jadi di server yang mendukung Java EE 6, di servlet Anda, Anda dapat menulis keduanya

@EJB EJBService ejbService;

dan

@Inject EJBService ejbService;

itulah yang bisa bikin bingung, tapi mungkin hanya itu yang jadi jembatan antara EJB dan CDI.

Ketika kita berbicara tentang CDI, Anda dapat memasukkan objek lain ke dalam kelas yang dikelola CDI (mereka hanya harus dibuat oleh kerangka kerja yang sadar CDI).

Apa lagi yang ditawarkan CDI ... Misalnya, Anda menggunakan Struts 2 sebagai kerangka kerja MVC (hanya sebagai contoh), dan Anda dibatasi di sini, bahkan menggunakan EJB 3.1 - Anda tidak dapat menggunakan @EJBanotasi dalam aksi Struts, itu tidak dikelola oleh kontainer. Tetapi ketika Anda menambahkan plugin Struts2-CDI, Anda dapat menulis di sana @Injectanotasi untuk hal yang sama (jadi tidak perlu lagi pencarian JNDI). Dengan cara ini ia meningkatkan kekuatan EJB, tetapi seperti yang saya sebutkan sebelumnya, apa yang Anda suntikkan dengan CDI - tidak masalah apakah itu terkait dengan EJB atau tidak, dan itulah kekuatannya.

PS. tautan yang diperbarui ke contoh

Maxym
sumber
Apakah @EJB dan @Inject benar-benar setara secara fungsional? Saya pikir metode injeksi yang tumpang tindih antara CDI dan beberapa sup akronim Java EE lainnya yang membuat saya bingung. Lebih banyak bacaan tampaknya menunjukkan bahwa ada harapan untuk menyelaraskan anotasi.
Tim
@Maxym Saat Anda menggunakan @ Inject, bagaimana Anda dapat memastikan bahwa @ Stateless atau komponen sisi server lain dari EJB masih menggunakan fitur seperti Pooling atau konkurensi yang ditawarkan oleh penampung. Saya harap ini tidak ditawarkan oleh CDI bukan?
Bala
1
@Bala: CDI tidak menawarkan pooling ... lihat CDI dengan atau tanpa EJB3.1 , semoga menjawab pertanyaan anda ..
Maxym
@KorayTugay: CDI adalah fitur Java EE, jadi semua server yang mendukung Java EE 6 memilikinya (Glassfish 3.0.1+ tidak salah, JBoss 6+ dll.) Anda dapat melihat JBoss Weld, implementasi CDI referensi yang Anda dapat digunakan di Tomcat misalnya ...
Maxym
191

Saat ini memang agak membingungkan karena sekarang ada beberapa model komponen di Java EE. Mereka adalah Kacang Dikelola CDI , EJB3 dan JSF .

CDI adalah anak baru di blok itu. Fitur kacang CDI dependency injection, scopingdan file event bus. Biji CDI adalah yang paling fleksibel dalam hal injeksi dan pelingkupan. Bus acara sangat ringan dan sangat cocok untuk aplikasi web yang paling sederhana sekalipun. Selain itu, CDI juga menampilkan fitur yang sangat canggih yang disebut portable extensions, yang merupakan semacam mekanisme plug-in bagi vendor untuk menyediakan fungsionalitas tambahan pada Java EE yang dapat tersedia di semua implementasi (Glassfish, JBoss AS, Websphere, dll) .

EJB3Biji dipasang dari model komponen EJB2 lama * dan merupakan biji pertama di Java EE yang dikelola biji melalui anotasi. Kacang EJB3 fitur dependency injection, declarative transactions, declarative security, pooling, concurrency control, asynchronous executiondan remoting.

Injeksi ketergantungan pada biji EJB3 tidak sefleksibel biji CDI dan biji EJB3 tidak memiliki konsep pelingkupan. Namun, biji EJB3 bersifat transaksional dan dikumpulkan secara default ** , dua hal yang sangat berguna yang telah dipilih CDI untuk ditinggalkan dalam domain EJB3. Item lain yang disebutkan juga tidak tersedia dalam CDI. EJB3 tidak memiliki event bus-nya sendiri, tetapi EJB3 memiliki jenis kacang khusus untuk mendengarkan pesan; pesan didorong kacang. Ini dapat digunakan untuk menerima pesan dari Sistem Pesan Java atau dari sistem lain yang memiliki adaptor sumber daya JCA. Menggunakan perpesanan lengkap untuk acara sederhana jauh lebih berat daripada bus acara CDI dan EJB3 hanya mendefinisikan pendengar, bukan API produsen.

Kacang Terkelola JSF telah ada di Java EE sejak JSF disertakan. Mereka juga menampilkan dependency injectiondan scoping. Kacang Terkelola JSF memperkenalkan konsep pelingkupan deklaratif. Awalnya cakupannya agak terbatas dan dalam versi Java EE yang sama di mana biji EJB3 sudah dapat dideklarasikan melalui anotasi, Kacang Terkelola JSF masih harus dideklarasikan dalam XML. Versi saat ini dari Kacang Terkelola JSF juga akhirnya dideklarasikan melalui anotasi dan cakupannya diperluas dengan cakupan tampilan dan kemampuan untuk membuat cakupan khusus. Cakupan tampilan, yang mengingat data di antara permintaan ke halaman yang sama adalah fitur unik dari Kacang Terkelola JSF.

Terlepas dari cakupan tampilan, masih sangat sedikit yang terjadi untuk JSF Managed Beans di Java EE 6. Cakupan tampilan yang hilang di CDI sangat disayangkan, karena jika tidak, CDI akan menjadi kumpulan super sempurna dari apa yang ditawarkan JSF Managed Beans. Pembaruan : Di Java EE 7 / JSF 2.2, @ViewScoped yang kompatibel dengan CDI telah ditambahkan, membuat CDI memang set super sempurna. Pembaruan 2 : Di JSF2.3, biji yang dikelola JSF sudah tidak digunakan lagi karena biji yang dikelola CDI.

Dengan EJB3 dan CDI situasinya tidak begitu jelas. Model dan API komponen EJB3 menawarkan banyak layanan yang tidak ditawarkan CDI, jadi biasanya EJB3 tidak dapat digantikan oleh CDI. Di sisi lain, CDI dapat digunakan dalam kombinasi dengan EJB3 - misalnya menambahkan dukungan cakupan ke EJB.

Reza Rahman, anggota kelompok ahli dan pelaksana implementasi CDI yang disebut CanDI, telah sering mengisyaratkan bahwa layanan yang terkait dengan model komponen EJB3 dapat dipasang sebagai sekumpulan penjelasan CDI. Jika itu terjadi, semua biji yang dikelola di Java EE bisa menjadi biji CDI. Ini tidak berarti bahwa EJB3 menghilang atau menjadi usang, tetapi fungsinya akan diekspos melalui CDI alih-alih melalui anotasi EJB sendiri seperti @Stateless dan @EJB.

Memperbarui

David Blevins dari TomEE dan OpenEJB ketenaran menjelaskan perbedaan dan persamaan antara CDI dan EJB dengan sangat baik di blognya: CDI, kapan harus keluar dari EJB

* Meskipun ini hanya peningkatan dalam nomor versi, kacang EJB3 sebagian besar adalah jenis kacang yang sama sekali berbeda: pojo sederhana yang menjadi "kacang terkelola" dengan menerapkan anotasi tunggal sederhana, vs model di EJB2 di mana kelas berat dan Deskripsi penyebaran XML yang terlalu bertele-tele diperlukan untuk setiap kacang, selain kacang yang diperlukan untuk mengimplementasikan berbagai kelas yang sangat berat dan sebagian besar antarmuka komponen yang tidak berarti.

** Biji sesi tanpa status biasanya dikumpulkan, biji sesi berstatus biasanya tidak (tetapi bisa juga). Karenanya, untuk kedua jenis penggabungan bersifat opsional dan spesifikasi EJB tidak mengamanatkannya.

Arjan Tijms
sumber
3
Saya agak bingung dengan pernyataan Anda bahwa "Kacang EJB3 tidak memiliki konsep pelingkupan" dan bahwa "EJB3 tidak memiliki bus acara sendiri". Bagaimana hal ini sesuai dengan klaim David Blevin bahwa "EJB adalah biji CDI dan karena itu memiliki semua manfaat CDI"? Apakah ada yang berubah dalam hal ini antara saat Anda menulis jawaban dan saat David menulis entri Blognya?
Chris
5
Ini karena konsep yang mungkin agak membingungkan sehingga sebenarnya sebenarnya bukan "biji CDI", tetapi ada layanan yang diterapkan pada biji terkelola. Untuk kepentingan diskusi, orang-orang (dan saya sendiri) menyebutnya sebagai "kacang CDI '. Sebelum CDI, kacang EJB tidak memiliki cakupan eksplisit. Seperti yang dijelaskan David, Stateful secara implisit memiliki cakupan apa pun (dan karenanya tidak ada cakupan secara khusus). Sekarang dengan CDI yang tersedia, biji EJB dapat memanfaatkan cakupan yang disediakan CDI. Tanpa spesifikasi CDI, jadi saat hanya melihat spesifikasi EJB, tidak ada cakupan eksplisit.
Arjan Tijms
1
Bisakah Anda menjelaskan apa yang Anda maksud dengan "ada layanan yang diterapkan pada biji terkelola"? Apakah itu berarti sebenarnya tidak ada yang namanya kacang CDI? Apakah hanya beberapa yang menyediakan fitur tambahan pada POJO - EJB - atau JSF Managed Bean? Suka bisa menggunakan penjelasan Inject di JSF Managed Bean?
Koray Tugay
3
@Chris untuk mengklarifikasi lebih lanjut dari perspektif spesifikasi EJB, kami membuat keputusan yang disengaja dari awal CDI untuk mewajibkan implementasi EJB harus mendukung 100% set fitur CDI pada EJB. Setiap aspek CDI berfungsi pada EJB dengan pengecualian cakupan yang harus kami batasi hanya untuk kacang Stateful.
David Blevins
1
Perhatikan bahwa JSF 2.2 sekarang menyediakan javax.faces.view.ViewScoped, ekstensi CDI yang pada dasarnya adalah port lingkup tampilan JSF ke CDI. Dengan ini, CDI adalah pengganti penuh untuk Kacang Terkelola JSF.
jdessey
-1

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

Ejbs dan CDI cukup mudah dimengerti.

Ejbs:

  1. Akan selalu dianotasi oleh qualifier cakupan, misalnya, @Stateless, @Stateful, @Request, dll.
  2. Contoh Ejbs dikendalikan oleh kerangka kerja Java EE dan dikumpulkan. Merupakan tugas kerangka kerja EE untuk menyediakan contoh bagi konsumen.

@Stateless

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

Pembuat Mobil dianotasi dengan lingkup Ejbs tertentu, oleh karena itu, itu adalah Ejb

CDI:

  1. Tidak sepenuhnya dikelola oleh kerangka kerja EE, instans harus dibuat sendiri.
  2. Itu selalu bergantung. izinkan saya menjelaskan "Tergantung" dengan contoh:

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

The Specificationkelas CDI, karena tidak dijelaskan dengan EJB lingkup dan juga ini telah ke diawali dengan kode Anda tidak framework EE. Satu hal yang perlu diperhatikan di sini adalah bahwa karena kami tidak memberi anotasi pada Specificationkelas, itu secara default Beranotasi oleh @Dependentanotasi.

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

Further reading: Anda perlu mempelajari lebih lanjut antara anotasi lingkup Ejbs dan anotasi cakupan CDI, yang selanjutnya akan menjelaskan konsep

HA S
sumber
Einstein juga berkata: "Segala Sesuatu Harus Dibuat Sesederhana Mungkin, Tapi Tidak Lebih Sederhana" Anda dapat (harus) mengganti 'dibuat' dengan 'dijelaskan' di sini.
Kukeltje