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:
- Kacang yang dikelola JSF
- Kacang yang dikelola CDI
- Biji yang dikelola EJB
- Dan bahkan Servlet adalah kacang yang dikelola karena dibuat instance-nya dan dihancurkan oleh wadah, yaitu wadah servlet.
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.
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
....
....
}
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 menggunakan javax.inject.Named
anotasi. Untuk menyuntikkan kacang ke kacang lain, Anda menganotasi bidang tersebut dengan javax.inject.Inject
anotasi.
@Named("someBean")
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
}
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:
- Transaksional
- Terpencil atau lokal
- Mampu pasif kacang stateful membebaskan sumber daya
- Mampu menggunakan timer
- Bisa asynchronous
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
atau javax.ejb.Stateful
anotasi ke kelas.
@Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
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
- gunakan modul seam- face atau MyFaces CODI . cukup tambahkan salah satunya ke classpath Anda dan
@ViewScoped
akan berfungsi di CDI. MyFaces CODI memiliki dukungan @ViewScoped yang lebih solid
- gunakan MyFaces CODI
@ViewAccessScoped
, ini adalah ekstensi yang ditulis di atas CDI oleh Apache, cukup unduh dan gunakan @ViewAccessScoped
anotasi sebagai gantinya @ViewScoped
.
- Gunakan CDI
@ConversationScoped
dan buat itu berjalan lama. Lihat di sini untuk info lebih lanjut .
- Gunakan anotasi Omnifaces @ViewScoped
Beberapa bagian dicuri dari sini .