Apa perbedaan antara @Inject dan @Autowired in Spring Framework? Yang mana yang digunakan dalam kondisi apa?

695

Saya akan melalui beberapa blog di SpringSource dan di salah satu blog, penulis menggunakan @Injectdan saya kira dia juga bisa menggunakan @Autowired.

Ini adalah bagian dari kode:

@Inject private CustomerOrderService customerOrderService;

Saya tidak yakin tentang perbedaan antara @Injectdan @Autowiredakan sangat menghargainya jika seseorang menjelaskan perbedaan mereka dan mana yang harus digunakan dalam situasi apa?

Rachel
sumber
3
Saya tidak punya jawaban, karena saya juga baru dalam hal ini, tetapi ini mungkin membantu sakaenakajima.wordpress.com/2010/08/10/…
Sagar V
2
Perbedaan antara '@Inject' dan '@Autowired' dijelaskan dengan baik di artikel ini alextheedom.wordpress.com/2016/02/13/…
Alex Theedom

Jawaban:

719

Dengan asumsi di sini Anda mengacu pada javax.inject.Injectanotasi. @Injectadalah bagian dari standar Java CDI ( Contexts and Dependency Injection ) yang diperkenalkan di Java EE 6 (JSR-299), baca selengkapnya . Spring telah memilih untuk mendukung penggunaan secara @Injectsinonim dengan @Autowiredanotasi mereka sendiri .

Jadi, untuk menjawab pertanyaan Anda, @Autowiredadalah anotasi Spring sendiri. @Injectadalah bagian dari teknologi Java baru yang disebut CDI yang mendefinisikan standar untuk injeksi ketergantungan mirip dengan Spring. Dalam aplikasi Spring, kedua anotasi bekerja dengan cara yang sama seperti Spring telah memutuskan untuk mendukung beberapa anotasi JSR-299 selain milik mereka.

pap
sumber
115
Jadi secara teori jika Anda menggunakan @Inject, Anda dapat mengganti pegas dengan kerangka kerja DI lainnya, mis. Guice dan menyuntikkan dependensi dengan cara yang sama.
Alex Barnes
71
Dengan risiko menjadi bertele-tele: @Injectadalah JSR yang terpisah (JSR-330) dari CDI (JSR-299).
Brad Cupit
36
Jika Anda hanya mengandalkan anotasi JSR- *, tentu saja, Anda dapat mengganti kerangka DI Anda. Tapi maukah kamu? Setelah Anda mulai menggunakan pegas, kemungkinan Anda telah menggunakan lebih banyak daripada hanya DI. Anda tidak akan hanya melakukan perubahan; dan bahkan jika Anda melakukannya, itu bukan beberapa pencarian & penggantian yang akan membuat atau menghancurkan langkah. Di sisi lain, anotasi Spring sendiri menawarkan lebih banyak fungsi. Menguasai kerangka kerja yang baik akan memberi Anda lebih banyak daripada hampir tidak menggunakan banyak.
Agoston Horvath
18
Saya setuju dengan Anda bahwa kami tidak sering mengubah kerangka kerja DI. Namun jika kode sumber kami memiliki beberapa paket dan jika Anda ingin membangun paket umum yang ingin Anda bagikan di beberapa proyek dan kemudian pergi dengan @Injectpenjelasan JSR lebih baik daripada menggunakan @Autowiredyang mengunci basis kode Anda dengan spring DI.
Aditya
3
Menggunakan @Injectsendiri tidak akan memastikan independensi kerangka kerja. Anda juga perlu mendeklarasikan kacang yang dapat disuntikkan tanpa mekanisme yang tergantung pada kerangka seperti Spring @Componentatau application.xml, tetapi gunakan @Nameddan @Singletondi tingkat kelas. Tidak tahu apakah ada proyek Musim Semi yang benar-benar menyatakan kacang seperti itu hari ini - Saya bahkan tidak pernah mendengar ada proyek yang bermigrasi dari Musim Semi ke JEE ...
Marcus K.
162

Berikut adalah posting blog yang membandingkan @Resource, @Injectdan @Autowired, dan tampaknya melakukan pekerjaan yang cukup komprehensif.

Dari tautan:

Dengan pengecualian pengujian 2 & 7, konfigurasi dan hasilnya identik. Ketika saya melihat di bawah tenda saya menentukan bahwa penjelasan '@Autowired' dan '@Inject' berperilaku identik. Kedua anotasi ini menggunakan 'AutowiredAnnotationBeanPostProcessor' untuk menyuntikkan dependensi. '@Autowired' dan '@Inject' dapat digunakan secara bergantian untuk menyuntikkan kacang Spring. Namun anotasi '@Resource' menggunakan 'CommonAnnotationBeanPostProcessor' untuk menyuntikkan dependensi. Meskipun mereka menggunakan kelas post processor yang berbeda, mereka semua berperilaku hampir identik. Di bawah ini adalah ringkasan dari jalur eksekusi mereka.

Tes 2 dan 7 yang referensi penulis adalah 'injeksi dengan nama bidang' dan 'upaya menyelesaikan kacang menggunakan kualifikasi buruk', masing-masing.

Kesimpulan harus memberi Anda semua informasi yang Anda butuhkan.

nicholas.hauschild
sumber
4
Artikel itu adalah penjelasan yang bagus tentang ketiga penjelasan. Saya harus membacanya lagi setelah sapuan pertama; tapi, artikel yang bagus sekali.
Thomas
1
Terima kasih banyak! Artikel ini menjawab beberapa jawaban saya dalam pencarian saya untuk menemukan perbedaan dan persamaan antara Spring dan JavaEE, serta beberapa pertanyaan lain yang saya miliki.
Kevin Cruijssen
36

Untuk menangani situasi di mana tidak ada kabel, kacang tersedia dengan @Autowired requiredatribut yang ditetapkan false.

Tetapi ketika menggunakan @Inject, antarmuka Penyedia bekerja dengan kacang yang berarti bahwa kacang tidak disuntikkan langsung tetapi dengan Penyedia.

Amits
sumber
8
Ini sangat penting, dan telah diabaikan dalam jawaban yang paling banyak dipilih.
Igor Donin
Secara default, parameter yang diperlukan disetel ke true untuk Autowired. Ref: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
tranquil
25

Sebagai Spring 3.0, musim semi menawarkan dukungan untuk JSR-330 penjelasan injeksi ketergantungan ( @Inject, @Named, @Singleton).

Ada bagian terpisah dalam dokumentasi Spring tentang mereka, termasuk perbandingan dengan setara Spring mereka.

Andre Steingress
sumber
Pertanyaan di sini, apa maksud Anda ketika Anda mengatakan Spring mendukung JSR? Bukankah wadah mendukung JSR independen dari Spring, dan persyaratan agar wadah mematuhi J2EE? Apakah maksud Anda membungkus fungsi? Jika Spring tidak "mendukung" itu, bukankah anotasi dari javax masih berfungsi secara default?
Dan Chase
Ini bukan keharusan untuk menjalankan Spring dalam wadah JEE, Anda juga dapat menggunakannya dalam wadah servlet / JSP seperti Tomcat dan masih memiliki dukungan JSR-330. Spring adalah wadah DI yang terpisah, itu tidak "menukar" kacang CDI dengan server JEE host jika itu yang Anda maksud. Anda bisa menggunakan CDI dalam wadah JEE, atau Spring bean - tetapi Anda tidak bisa menggunakan keduanya (di luar kotak).
Andre Steingress
22

Perbedaan utama (diperhatikan saat membaca Spring Documents ) antara @Autowireddan @Injectadalah, @Autowiredmemiliki atribut 'wajib' sedangkan @Inject tidak memiliki atribut 'wajib'.

Beruntung
sumber
apa yang kamu maksudkan dengan diminta?
mattyman
2
@mattymanme Dari dokumen, "Secara default, autowiring gagal setiap kali nol kandidat kacang tersedia; perilaku default adalah memperlakukan metode, konstruktor, dan bidang yang dijelaskan sebagai indikasi ketergantungan yang diperlukan. Perilaku ini dapat diubah dengan mengatur atribut yang diperlukan ke false ". Misalnya: @Autowired(required=false).Dalam istilah sederhana, " requiredAtribut menunjukkan bahwa properti tidak diperlukan untuk keperluan autowiring, properti diabaikan jika tidak dapat diotomatisasikan."
Beruntung
lihat ke kode sumber antarmuka publik Autowired {/ ** * Menyatakan apakah diperlukan ketergantungan beranotasi. * / diperlukan boolean () default true; } antarmuka publik Suntikkan {}
tarn
15

Lebih baik gunakan @Inject sepanjang waktu. Karena itu adalah pendekatan konfigurasi java (disediakan oleh sun) yang membuat aplikasi kita agnostic ke framework. Jadi, jika Anda musim semi juga kelas Anda akan bekerja.

Jika Anda menggunakan @Autowired, itu hanya akan berfungsi dengan pegas karena @Autowired adalah pegas yang menyediakan anotasi.

tech.yenduri
sumber
13
Sun sudah mati. Hidup matahari.
Amrinder Arora
6
seberapa sering Anda akan mengubah kerangka kerja? hanya ingin tahu
Kay
Pada sebagian besar proyek saya melihat Autowired daripada Suntikan. Saya mengerti alasan dari jawabannya, tetapi saya tidak bisa menjawabnya.
Witold Kaczurba
13

@Autowired anotasi didefinisikan dalam kerangka Spring.

@Injectanotasi adalah anotasi standar, yang didefinisikan dalam standar "Injeksi Ketergantungan untuk Java" (JSR-330) . Pegas (sejak versi 3.0) mendukung model umum injeksi ketergantungan yang didefinisikan dalam JSR-330 standar. ( Kerangka kerja Google Guice dan kerangka kerja Picocontainer juga mendukung model ini).

Dengan @Injectdapat disuntikkan referensi ke implementasi Providerantarmuka, yang memungkinkan menyuntikkan referensi yang ditangguhkan.

Anotasi @Injectdan @Autowired- adalah analogi yang hampir lengkap. Selain @Autowiredanotasi, @Injectanotasi dapat digunakan untuk properti, metode, dan konstruktor yang mengikat secara otomatis.

Berbeda dengan @Autowiredanotasi, @Injectanotasi tidak memiliki requiredatribut. Oleh karena itu, jika dependensi tidak akan ditemukan - akan dilemparkan pengecualian.

Ada juga perbedaan dalam klarifikasi sifat pengikatan. Jika ada ambiguitas dalam pemilihan komponen untuk injeksi, @Namedkualifikasi harus ditambahkan. Dalam situasi yang serupa untuk @Autowiredanotasi akan ditambahkan @Qualifierkualifikasi (JSR-330 mendefinisikan @Qualifieranotasi itu sendiri dan melalui anotasi kualifikasi @Namedini ditentukan).

Arash
sumber
Meskipun '@Inject' tidak memiliki atribut yang diperlukan, status Java Docs: Diperlukan suntikan anggota yang ditandai dengan '@Inject'. Yang tampaknya menyiratkan bahwa jika anggota tidak ditemukan suntikannya akan gagal. Lihat Java Docs: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom
12

@Inject tidak memiliki atribut 'wajib'

Mykhaylo Adamovych
sumber
12

Selain yang di atas:

  1. Ruang lingkup default untuk @Autowiredkacang adalah Singleton sedangkan dengan menggunakan JSR 330 @Injectpenjelasan itu seperti prototipe Spring .
  2. Tidak ada yang setara dengan @Lazy di JSR 330 menggunakan @Inject.
  3. Tidak ada yang setara dengan @Nilai dalam JSR 330 menggunakan @Inject.
Keyur Vyas
sumber
0

The @Injectpenjelasan adalah salah satu koleksi JSR-330 penjelasan. Ini memiliki Pencocokan berdasarkan Jenis, Pencocokan dengan Kualifikasi, Pencocokan dengan jalur eksekusi Nama. Jalur eksekusi ini berlaku untuk penyetel dan injeksi lapangan. Perilaku @Autowiredanotasi sama dengan @Injectanotasi. Satu-satunya perbedaan adalah @Autowiredpenjelasan adalah bagian dari kerangka Spring. @Autowiredanotasi juga memiliki jalur eksekusi di atas. Jadi saya sarankan @Autowireduntuk jawaban Anda.

Kushani5j
sumber