Ya, Anda dapat dengan bebas mencampur CDI dan EJB dan mendapatkan hasil yang luar biasa. Sepertinya Anda sedang menggunakan @WebService
dan @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
, @Stateless
atau @Singleton
anotasi 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 @Stateful
kacang 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 @Stateful
pada dasarnya adalah kacang "bercakupan apapun". Ini @Stateless
pada dasarnya adalah kumpulan instance - Anda mendapatkan instance dari kumpulan selama satu pemanggilan. Ini @Singleton
pada 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
, @Stateless
atau @Singleton
di atasnya.
Berikut daftar singkat saat saya keluar dari EJB.
Menggunakan JAX-WS
Mengekspos JAX-WS @WebService
. Aku malas. Jika @WebService
juga merupakan EJB, Anda tidak perlu mencantumkannya dan memetakannya sebagai servlet di web.xml
file. 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 @Stateless
dan @Singleton
hanya.
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 Application
subkelas JAX-RS atau semacamnya. Ditambah saya dapat mengekspos kacang yang sama persis seperti @WebService
jika saya ingin atau menggunakan salah satu fungsi hebat yang disebutkan di bawah ini.
Tersedia untuk @Stateless
dan @Singleton
hanya.
Logika startup
Muat saat memulai melalui @Startup
. Saat ini tidak ada yang setara dengan ini di CDI. Entah bagaimana kami melewatkan menambahkan sesuatu seperti AfterStartup
acara dalam siklus hidup kontainer. Seandainya kami melakukan ini, Anda bisa saja memiliki @ApplicationScoped
kacang yang mendengarkannya dan itu akan secara efektif sama dengan @Singleton
dengan @Startup
. Itu ada di daftar untuk CDI 1.1.
Tersedia @Singleton
hanya untuk .
Bekerja secara Paralel
@Asynchronous
pemanggilan 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
, @Stateless
dan @Singleton
.
Menjadwalkan pekerjaan
@Schedule
atau ScheduleExpression
pada dasarnya adalah sebuah cron atau Quartz
fungsionalitas. 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 EntityManager
panggilan tetap gagal atau ada masalah flushing, tidak perlu membatalkan pekerjaan. Hore, transaksi.
Tersedia untuk @Stateless
dan @Singleton
hanya.
Menggunakan EntityManagers dalam transaksi JTA
Catatan tentang transaksi di atas tentu saja mengharuskan Anda menggunakan JTA
managed EntityManager
. Anda dapat menggunakannya dengan "CDI" biasa, tetapi tanpa transaksi yang dikelola container, duplikasi UserTransaction
logika commit / rollback bisa sangat monoton .
Tersedia untuk semua komponen Java EE termasuk CDI, JSF @ManagedBean
, @WebServlet
, @WebListener
, @WebFilter
, dll @TransactionAttribute
penjelasan, bagaimanapun, tersedia untuk @Stateful
, @Stateless
dan @Singleton
hanya.
Menjaga JTA tetap dikelola EntityManager
The EXTENDED
berhasil EntityManager
memungkinkan Anda untuk tetap EntityManager
terbuka antara JTA
transaksi dan tidak kehilangan data cache. Fitur bagus untuk waktu dan tempat yang tepat. Gunakan secara bertanggung jawab :)
Tersedia @Stateful
hanya 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 @Singleton
hanya untuk kacang.