Saya merasa ada sedikit kekacauan di spek Java EE 6. Ada beberapa set anotasi.
Kami memiliki javax.ejb
anotasi seperti @Stateful
dan @Stateless
untuk membuat EJB.
Ada juga yang @javax.annotation.ManagedBean
membuat kacang yang dikelola.
Ada anotasi dalam javax.enterprise.context
like @SessionScoped
dan @RequestScoped
.
Terlebih lagi ada juga @ManagedBean
dan @SessionScoped
/ @RequestScoped
keterangan dalam javax.faces.bean
paket.
Dan untuk membuat acara lebih rumit ada paket javax.inject
dengan @Named
anotasi.
Bisakah seseorang menjelaskan bagaimana mereka terkait satu sama lain?
Di mana saya bisa menggunakan @EJB
, @Inject
atau @ManagedPropery
menyuntikkan kacang lain?
java
jakarta-ee
java-ee-6
cdi
Piotr Gwiazda
sumber
sumber
Jawaban:
Pertama-tama izinkan saya melakukan beberapa klarifikasi:
Definisi kacang yang dikelola : umumnya kacang yang dikelola adalah objek yang siklus hidupnya (konstruksi, penghancuran, dll) dikelola oleh sebuah wadah.
Di Java ee kami memiliki banyak container yang mengatur daur hidup objeknya, seperti container JSF, container EJB, container CDI, container Servlet, dll.
Semua kontainer ini bekerja secara independen, mereka boot dalam inisialisasi server aplikasi dan memindai kelas dari semua artefak termasuk jar, ejb-jar, file perang dan telinga dalam waktu penyebaran dan mengumpulkan dan menyimpan beberapa metadata tentang mereka, lalu ketika Anda membutuhkan objek dari kelas saat runtime mereka akan memberi Anda contoh dari kelas-kelas itu dan setelah menyelesaikan pekerjaan, mereka akan menghancurkannya.
Jadi kami dapat mengatakan bahwa kami memiliki:
Jadi ketika Anda melihat kata Managed Bean, Anda harus bertanya tentang konteks atau jenisnya. (JSF, CDI, EJB, dll.)
Kemudian Anda mungkin bertanya mengapa kami memiliki banyak kontainer ini: AFAIK, Java EE guys ingin memiliki kerangka kerja injeksi ketergantungan, tetapi mereka tidak dapat mengumpulkan semua persyaratan dalam satu spesifikasi karena mereka tidak dapat memprediksi persyaratan masa depan dan mereka membuat EJB 1.0 dan kemudian 2.0 dan kemudian 3.0 dan sekarang 3.1 tetapi target EJB hanya untuk beberapa persyaratan (transaksi, model komponen terdistribusi, dll).
Pada saat yang sama (secara paralel) mereka menyadari bahwa mereka perlu mendukung JSF juga, kemudian mereka membuat biji yang dikelola JSF dan wadah lain untuk biji JSF dan mereka menganggapnya sebagai wadah DI yang matang, tetapi tetap saja itu bukan wadah yang lengkap dan matang.
Setelah itu Gavin King dan beberapa orang baik lainnya;) membuat CDI yang merupakan wadah DI paling matang yang pernah saya lihat. CDI (terinspirasi oleh Seam2, Guice dan Spring) dibuat untuk mengisi celah antara JSF dan EJB dan banyak hal berguna lainnya seperti injeksi pojo, metode produser, interseptor, dekorator, integrasi SPI, sangat fleksibel, dll. Dan bahkan dapat dilakukan apa yang dilakukan biji terkelola EJB dan JSF maka kita hanya dapat memiliki satu wadah DI yang matang dan kuat. Tetapi untuk beberapa kompatibilitas mundur dan alasan politik Java EE guys ingin menyimpannya !!!
Di sini Anda dapat menemukan perbedaan dan kasus penggunaan untuk masing-masing jenis ini:
Kacang Terkelola JSF, Kacang CDI, dan EJB
JSF pada awalnya dikembangkan dengan kacang yang dikelola sendiri dan mekanisme injeksi ketergantungan yang ditingkatkan untuk JSF 2.0 untuk menyertakan kacang berbasis anotasi. Ketika CDI dirilis dengan Java EE 6, itu dianggap sebagai kerangka kerja kacang yang dikelola untuk platform itu dan tentu saja, EJB ketinggalan jaman semuanya telah ada selama lebih dari satu dekade.
Masalahnya tentu saja mengetahui mana yang akan digunakan dan kapan menggunakannya.
Mari kita mulai dengan kacang Terkelola JSF yang paling sederhana.
Kacang Terkelola JSF
Singkatnya, jangan gunakan jika Anda mengembangkan untuk Java EE 6 dan menggunakan CDI. Mereka menyediakan mekanisme sederhana untuk injeksi ketergantungan dan menentukan kacang pendukung untuk halaman web, tetapi mereka jauh lebih lemah daripada kacang CDI.
Mereka dapat ditentukan menggunakan
@javax.faces.bean.ManagedBean
anotasi yang mengambil parameter nama opsional. Nama ini dapat digunakan untuk mereferensikan kacang dari halaman JSF.Cakupan dapat diterapkan ke bean menggunakan salah satu cakupan berbeda yang ditentukan dalam
javax.faces.bean
paket yang mencakup cakupan permintaan, sesi, aplikasi, tampilan, dan kustom.Kacang JSF tidak dapat dicampur dengan jenis biji lainnya tanpa kode manual.
Kacang CDI
CDI adalah kerangka kerja pengelolaan kacang dan injeksi ketergantungan yang dirilis sebagai bagian dari Java EE 6 dan ini mencakup fasilitas kacang terkelola yang lengkap dan lengkap. Biji CDI jauh lebih maju dan fleksibel daripada biji yang dikelola JSF sederhana. Mereka dapat menggunakan interseptor, ruang lingkup percakapan, Acara, jenis injeksi aman, dekorator, stereotip, dan metode produsen.
Untuk menyebarkan kacang CDI, Anda harus menempatkan file bernama beans.xml dalam folder META-INF di classpath. Setelah Anda melakukan ini, maka setiap kacang dalam paket menjadi kacang CDI. Ada banyak fitur di CDI, terlalu banyak untuk dibahas di sini, tetapi sebagai referensi cepat untuk fitur mirip JSF, Anda dapat menentukan cakupan kacang CDI menggunakan salah satu cakupan yang ditentukan dalam
javax.enterprise.context
paket (yaitu, permintaan, percakapan , cakupan sesi dan aplikasi). Jika Anda ingin menggunakan kacang CDI dari halaman JSF, Anda dapat memberinya nama menggunakanjavax.inject.Named
anotasi. Untuk menyuntikkan kacang ke kacang lain, Anda menganotasi bidang tersebut denganjavax.inject.Inject
anotasi.Injeksi otomatis seperti yang dijelaskan di atas dapat dikontrol melalui penggunaan Kualifikasi yang dapat membantu mencocokkan kelas tertentu yang ingin Anda injeksi. Jika Anda memiliki beberapa jenis pembayaran, Anda dapat menambahkan kualifikasi apakah itu asinkron atau tidak. Meskipun Anda dapat menggunakan
@Named
anotasi sebagai qualifier, Anda tidak boleh seperti yang disediakan untuk mengekspos kacang dalam EL.CDI menangani injeksi biji dengan cakupan yang tidak cocok melalui penggunaan proxy. Oleh karena itu, Anda dapat memasukkan kacang cakupan permintaan ke dalam kacang cakupan sesi dan referensi akan tetap valid pada setiap permintaan karena untuk setiap permintaan, proxy akan terhubung kembali ke instance langsung dari kacang cakupan permintaan.
CDI juga memiliki dukungan untuk interseptor, acara, cakupan percakapan baru, dan banyak fitur lainnya yang menjadikannya pilihan yang jauh lebih baik daripada kacang yang dikelola JSF.
EJB
EJB mendahului biji CDI dan dalam beberapa hal mirip dengan biji CDI dan dalam hal lain sangat berbeda. Terutama, perbedaan antara kacang CDI dan EJB adalah bahwa EJB adalah:
Kedua jenis EJB disebut stateless dan stateful. Stateless EJB dapat dianggap sebagai kacang sekali pakai yang aman untuk thread yang tidak mempertahankan status apa pun di antara dua permintaan web. EJB yang berstatus memiliki status tahan dan dapat dibuat serta diam selama dibutuhkan hingga dibuang.
Mendefinisikan EJB itu sederhana, Anda cukup menambahkan
javax.ejb.Stateless
ataujavax.ejb.Stateful
anotasi ke kelas.Kacang stateless harus memiliki cakupan dependen sementara kacang sesi stateful dapat memiliki cakupan apa pun. Secara default, transaksi bersifat transaksional, tetapi Anda dapat menggunakan anotasi atribut transaction.
Meskipun EJB dan biji CDI sangat berbeda dalam hal fitur, penulisan kode untuk mengintegrasikannya sangat mirip karena biji CDI dapat disuntikkan ke dalam EJB dan EJB dapat disuntikkan ke dalam biji CDI. Tidak perlu membuat perbedaan saat menyuntikkan satu sama lain. Sekali lagi, cakupan yang berbeda ditangani oleh CDI melalui penggunaan proxy. Satu pengecualian untuk ini adalah bahwa CDI tidak mendukung injeksi EJB jarak jauh tetapi dapat diimplementasikan dengan menulis metode produser sederhana untuknya.
The
javax.inject.Named
penjelasan serta setiap Kualifikasi dapat digunakan pada EJB untuk mencocokkannya dengan titik injeksi.Kapan menggunakan kacang yang mana
Bagaimana Anda tahu kapan harus menggunakan kacang yang mana? Sederhana.
Jangan pernah menggunakan kacang yang dikelola JSF kecuali Anda bekerja dalam wadah servlet dan tidak ingin mencoba membuat CDI bekerja di Tomcat (walaupun ada beberapa arketipe Maven untuk itu sehingga tidak ada alasan).
Secara umum, Anda harus menggunakan kacang CDI kecuali Anda membutuhkan fungsionalitas lanjutan yang tersedia di EJB seperti fungsi transaksional. Anda dapat menulis interseptor Anda sendiri untuk membuat kacang CDI menjadi transaksional, tetapi untuk saat ini, lebih mudah menggunakan EJB sampai CDI mendapatkan kacang CDI transaksional yang berada di sekitar sudut. Jika Anda terjebak dalam wadah servlet dan menggunakan CDI, maka transaksi tulisan tangan atau interseptor transaksi Anda sendiri adalah satu-satunya pilihan tanpa EJB.
Jika Anda perlu menggunakan
@ViewScoped
CDI Anda harus@ViewScoped
akan berfungsi di CDI. MyFaces CODI memiliki dukungan @ViewScoped yang lebih solid@ViewAccessScoped
, ini adalah ekstensi yang ditulis di atas CDI oleh Apache, cukup unduh dan gunakan@ViewAccessScoped
anotasi sebagai gantinya@ViewScoped
.@ConversationScoped
dan buat itu berjalan lama. Lihat di sini untuk info lebih lanjut .Beberapa bagian dicuri dari sini .
sumber
@ManagedProperty("#{someBean})"
cara yang tepat?@Named
dan@javax.enterprise.context.RequestScoped
dan gunakan injeksi CDI menggunakan anotasi @Inject. jangan gunakan kacang yang dikelola jsf jika Anda tidak perlu;).Ya, ini bisa membingungkan.
Untuk beberapa alasan historis ehm, JSF dan CDI menggunakan anotasi yang sama untuk cakupan, tetapi dari paket yang berbeda.
Seperti yang mungkin Anda tebak, itu berasal
javax.faces.bean
dari spesifikasi JSF, dan tidak terkait dengan CDI. Jangan menggunakannya kecuali Anda memiliki alasan yang sangat kuat untuk melakukannya. Dan jangan pernah mencampurnya dengan penjelasan CDI darijavax.ejb
. Ini akan menghasilkan daftar bug dan anomali halus yang tak ada habisnya.Saya biasanya menyarankan Anda membaca sekilas beberapa halaman pertama (atau bahkan lebih) dari dokumentasi Weld yang sangat bagus . Ini akan menempatkan Anda pada jalur untuk Java EE 6.
Dan jangan ragu untuk memposting pertanyaan lebih lanjut di sini.
sumber
@javax.annotation.ManagedBean
tidak ada gunanya karena CDI memperlakukan semua kelas sebagai kacang yang dikelola, benar kan?Karena tidak ada balasan secara khusus tentang
@javax.annotation.ManagedBean
, berikut link ke jawaban dari pertanyaan serupa: Backing beans (@ManagedBean) atau CDI Beans (@Named)? . Spesifikasi dapat ditemukan di http://download.oracle.com/otndocs/jcp/managed_beans-1.0-fr-eval-oth-JSpec/ . Jadi menurut saya@javax.annotation.ManagedBean
itu dimaksudkan sebagai generalisasi@javax.faces.bean.ManagedBean
.Dari apa yang saya kumpulkan, Kacang Terkelola JSF dihapuskan demi Kacang CDI (mungkin sudah tidak digunakan lagi dari JSF 2.3?), Jadi saya rasa
@javax.annotation.ManagedBean
itu semua semakin usang sekarang.sumber
@Named
akan menggantikan@ManagedBean
di masa depan?@Named
kacang CDI akan menggantikan JSF@ManagedBeans
, misalnya di stackoverflow.com/questions/4347374/… , BalusC mengatakan "Harapannya adalah bahwa @ManagedBean dan kawan-kawan akan dihentikan sesuai dengan Java EE 8. ".