Ya, Anda dapat dengan bebas mencampur CDI dan EJB dan mendapatkan hasil yang luar biasa. Sepertinya Anda sedang menggunakan @WebServicedan @Schedule, itulah alasan bagus untuk menambahkan EJB ke dalam campuran.
Ada banyak kebingungan di luar sana, jadi berikut adalah beberapa informasi umum tentang EJB dan CDI yang terkait satu sama lain.
EJB> = CDI
Perhatikan bahwa EJB adalah biji CDI dan karena itu memiliki semua manfaat CDI. Kebalikannya tidak benar (belum). Jadi pastinya jangan biasakan berpikir "EJB vs CDI" karena logika itu diterjemahkan menjadi "EJB + CDI vs CDI", yang merupakan persamaan ganjil.
Di versi Java EE yang akan datang, kami akan terus menyelaraskannya. Yang dimaksud dengan menyelaraskan adalah memungkinkan orang melakukan apa yang sudah bisa mereka lakukan, hanya tanpa @Stateful, @Statelessatau @Singletonanotasi di atas.
EJB dan CDI dalam Ketentuan Pelaksanaan
Pada akhirnya, EJB dan CDI berbagi desain fundamental yang sama sebagai komponen yang diproksikan. Ketika Anda mendapatkan referensi ke kacang EJB atau CDI, itu bukanlah kacang yang sebenarnya. Sebaliknya objek yang Anda berikan adalah palsu (proxy). Saat Anda memanggil metode pada objek palsu ini, panggilan masuk ke container yang akan mengirim panggilan melalui interseptor, dekorator, dll. Serta menangani transaksi atau pemeriksaan keamanan. Setelah semua selesai, panggilan akhirnya masuk ke objek nyata dan hasilnya akan diteruskan kembali melalui proxy ke pemanggil.
Perbedaannya hanya terletak pada bagaimana objek yang akan dipanggil diselesaikan. Yang kami maksud dengan "diselesaikan" adalah, di mana dan bagaimana penampung mencari instance nyata untuk dipanggil.
Dalam CDI, penampung melihat dalam "cakupan", yang pada dasarnya akan menjadi peta hash yang berlaku untuk jangka waktu tertentu (per permintaan @RequestScoped, per Sesi HTTP @SessionScoped, per aplikasi @ApplicationScoped, Percakapan JSF @ConversationScoped, atau per implementasi cakupan khusus Anda).
Di EJB, container juga melihat ke dalam hashmap jika kacang bertipe @Stateful. Sebuah @Statefulkacang juga dapat menggunakan salah satu penjelasan ruang lingkup di atas menyebabkan ia hidup dan mati dengan semua kacang-kacangan lainnya dalam ruang lingkup. Dalam EJB @Statefulpada dasarnya adalah kacang "bercakupan apapun". Ini @Statelesspada dasarnya adalah kumpulan instance - Anda mendapatkan instance dari kumpulan selama satu pemanggilan. Ini @Singletonpada dasarnya@ApplicationScoped
Jadi pada level fundamental, apapun yang dapat Anda lakukan dengan bean "EJB", Anda harus bisa melakukan bean "CDI". Di bawah selimut, sangat sulit untuk membedakan mereka. Semua pipa ledeng sama dengan pengecualian bagaimana kasus diselesaikan.
Mereka saat ini tidak sama dalam hal layanan yang akan ditawarkan kontainer saat melakukan proxy ini, tetapi seperti yang saya katakan kami sedang mengerjakannya di tingkat spesifikasi Java EE.
Catatan kinerja
Abaikan gambaran mental "ringan" atau "berat" yang mungkin Anda miliki. Itu semua tentang pemasaran. Mereka memiliki desain internal yang sama untuk sebagian besar. Resolusi contoh CDI mungkin sedikit lebih kompleks karena sedikit lebih dinamis dan kontekstual. Resolusi instans EJB cukup statis, bodoh dan sederhana sebagai perbandingan.
Saya dapat memberi tahu Anda dari perspektif implementasi di TomEE, ada tentang perbedaan kinerja nol antara memanggil EJB vs memanggil kacang CDI.
Default ke POJO, lalu CDI, lalu EJB
Tentunya jangan gunakan CDI atau EJB bila tidak ada manfaatnya. Masukkan CDI ketika Anda mulai menginginkan injeksi, peristiwa, interseptor, dekorator, pelacakan siklus hidup, dan hal-hal seperti itu. Itu paling sering.
Di luar mereka dasar-dasar, ada sejumlah layanan kontainer berguna Anda hanya memiliki pilihan untuk menggunakan jika Anda membuat CDI kacang Anda juga EJB dengan menambahkan @Stateful, @Statelessatau @Singletondi atasnya.
Berikut daftar singkat saat saya keluar dari EJB.
Menggunakan JAX-WS
Mengekspos JAX-WS @WebService. Aku malas. Jika @WebServicejuga merupakan EJB, Anda tidak perlu mencantumkannya dan memetakannya sebagai servlet di web.xmlfile. Itu berhasil bagi saya. Selain itu, saya mendapatkan opsi untuk menggunakan salah satu fungsi lain yang disebutkan di bawah ini. Jadi itu tidak perlu dipikirkan lagi bagi saya.
Tersedia untuk @Statelessdan @Singletonhanya.
Menggunakan JAX-RS
Mengekspos sumber daya JAX-RS melalui @Path. Saya masih malas. Ketika layanan RESTful juga merupakan EJB, sekali lagi Anda mendapatkan penemuan otomatis dan tidak perlu menambahkannya ke Applicationsubkelas JAX-RS atau semacamnya. Ditambah saya dapat mengekspos kacang yang sama persis seperti @WebServicejika saya ingin atau menggunakan salah satu fungsi hebat yang disebutkan di bawah ini.
Tersedia untuk @Statelessdan @Singletonhanya.
Logika startup
Muat saat memulai melalui @Startup. Saat ini tidak ada yang setara dengan ini di CDI. Entah bagaimana kami melewatkan menambahkan sesuatu seperti AfterStartupacara dalam siklus hidup kontainer. Seandainya kami melakukan ini, Anda bisa saja memiliki @ApplicationScopedkacang yang mendengarkannya dan itu akan secara efektif sama dengan @Singletondengan @Startup. Itu ada di daftar untuk CDI 1.1.
Tersedia @Singletonhanya untuk .
Bekerja secara Paralel
@Asynchronouspemanggilan metode. Memulai utas adalah larangan di lingkungan sisi server mana pun. Memiliki terlalu banyak utas adalah pembunuh kinerja yang serius. Anotasi ini memungkinkan Anda untuk memparalelkan hal-hal yang Anda lakukan menggunakan kumpulan utas penampung. Ini luar biasa.
Tersedia untuk @Stateful, @Statelessdan @Singleton.
Menjadwalkan pekerjaan
@Scheduleatau ScheduleExpressionpada dasarnya adalah sebuah cron atau Quartzfungsionalitas. Juga sangat mengagumkan. Sebagian besar wadah hanya menggunakan Quartz di bawah penutup untuk ini. Namun, kebanyakan orang tidak tahu bahwa penjadwalan di Java EE bersifat transaksional! Jika Anda memperbarui database lalu menjadwalkan beberapa pekerjaan dan salah satunya gagal, keduanya akan secara otomatis dibersihkan. Jika EntityManagerpanggilan tetap gagal atau ada masalah flushing, tidak perlu membatalkan pekerjaan. Hore, transaksi.
Tersedia untuk @Statelessdan @Singletonhanya.
Menggunakan EntityManagers dalam transaksi JTA
Catatan tentang transaksi di atas tentu saja mengharuskan Anda menggunakan JTAmanaged EntityManager. Anda dapat menggunakannya dengan "CDI" biasa, tetapi tanpa transaksi yang dikelola container, duplikasi UserTransactionlogika commit / rollback bisa sangat monoton .
Tersedia untuk semua komponen Java EE termasuk CDI, JSF @ManagedBean, @WebServlet, @WebListener, @WebFilter, dll @TransactionAttributepenjelasan, bagaimanapun, tersedia untuk @Stateful, @Statelessdan @Singletonhanya.
Menjaga JTA tetap dikelola EntityManager
The EXTENDEDberhasil EntityManagermemungkinkan Anda untuk tetap EntityManagerterbuka antara JTAtransaksi dan tidak kehilangan data cache. Fitur bagus untuk waktu dan tempat yang tepat. Gunakan secara bertanggung jawab :)
Tersedia @Statefulhanya untuk .
Sinkronisasi mudah
Saat Anda membutuhkan sinkronisasi, anotasi @Lock(READ)dan @Lock(WRITE)cukup bagus. Ini memungkinkan Anda untuk mendapatkan manajemen akses bersamaan secara gratis. Lewati semua pipa ledeng ReentrantReadWriteLock. Di bucket yang sama is @AccessTimeout, yang memungkinkan Anda untuk mengatakan berapa lama thread harus menunggu untuk mendapatkan akses ke instance bean sebelum menyerah.
Tersedia @Singletonhanya untuk kacang.