Spring @Autowired digunakan

218

Apa pro dan kontra dari penggunaan @Autowired di kelas yang akan ditransfer oleh Spring?

Hanya untuk memperjelas, saya sedang berbicara secara khusus tentang anotasi @Autowired , bukan pengkabelan otomatis dalam XML.

Saya mungkin hanya tidak memahaminya, tetapi bagi saya itu hampir tampak seperti anti-pola - kelas Anda mulai menjadi sadar bahwa mereka terikat pada kerangka kerja DI, bukan hanya menjadi POJO. Mungkin saya pelahap untuk hukuman, tapi saya suka memiliki konfigurasi XML eksternal untuk kacang, dan saya suka memiliki wirings eksplisit, jadi saya tahu persis apa yang ditransfer di mana.

Andy White
sumber
4
Saya tertarik pada subjek ini juga - mengonfigurasi aplikasi MVC Anda melalui anotasi dan bukannya XML sepertinya akan menyebabkan banyak pencarian "kelas mana yang dipetakan ke URL ini?" "siapa yang menangani ini?" Saya ingin memiliki sumber konfigurasi tunggal
matt b
6
istilah "@Autowiring" tampaknya menyesatkan di sini. Karena Anda juga dapat melakukan autowiring dengan konfigurasi XML, pertanyaan awal harus diulang menjadi "Pro dan kontra menggunakan anotasi Spring". Jawaban yang diberikan lebih fokus pada aspek autowiring dan lebih sedikit pada aspek menggunakan anotasi.
Neeme Praks
Kemungkinan rangkap dari Understanding Spring @Autowired use
tkruse

Jawaban:

253

Untuk waktu yang lama saya percaya bahwa ada nilai dalam memiliki "konfigurasi terpusat, deklaratif," seperti file xml yang kita semua gunakan. Kemudian saya menyadari bahwa sebagian besar hal dalam file bukan konfigurasi - tidak pernah berubah di mana pun setelah pengembangan, tidak pernah. Kemudian saya menyadari bahwa "terpusat" hanya memiliki nilai dalam sistem yang cukup kecil - hanya dalam sistem kecil Anda akan pernah dapat melakukan grok file konfigurasi secara keseluruhan . Dan apa sebenarnya nilai memahami perkabelan secara keseluruhan, ketika "wirings" yang sama sebagian besar diduplikasi oleh dependensi dalam kode? Jadi satu-satunya yang saya simpan adalah meta-data (anotasi), yang masih semacam deklaratif. Ini tidak pernah berubah saat runtime dan mereka tidak pernah "konfigurasi" data yang akan diubah seseorang dengan cepat - jadi saya pikir menyimpannya dalam kode itu bagus.

Saya menggunakan kabel-otomatis penuh sebanyak yang saya bisa. Aku menyukainya. Saya tidak akan kembali ke musim semi gaya lama kecuali mengancam di titik senjata. Alasan saya untuk lebih memilih sepenuhnya @Autowiredtelah berubah seiring waktu.

Saat ini saya pikir alasan paling penting untuk menggunakan autowiring adalah karena ada satu abstraksi yang kurang dalam sistem Anda untuk melacak. "Nama kacang" secara efektif hilang. Ternyata nama kacang hanya ada karena xml. Jadi lapisan penuh tipuan abstrak (di mana Anda akan memasukkan nama "foo" menjadi "bar" kacang) hilang. Sekarang saya menghubungkan antarmuka "Foo" ke dalam kacang saya secara langsung, dan implementasi dipilih oleh profil run-time. Ini memungkinkan saya untuk bekerja dengan kode ketika melacak dependensi dan implementasi. Ketika saya melihat ketergantungan autowired dalam kode saya, saya hanya bisa menekan tombol "pergi ke implementasi" di IDE saya dan kemudian muncul daftar implementasi yang dikenal. Dalam kebanyakan kasus hanya ada satu implementasi dan saya langsung ke kelas. Bisa' implementasi apa yang sedang digunakan (saya mengklaim bahwa kebalikannya lebih dekat dengan kebenaran dengan kabel xml - lucu bagaimana perspektif Anda berubah!)

Sekarang Anda dapat mengatakan bahwa itu hanya lapisan yang sangat sederhana, tetapi setiap lapisan abstraksi yang kami tambahkan ke sistem kami menambah kompleksitas. Saya benar-benar tidak berpikir xml pernah menambahkan nilai nyata ke sistem apa pun yang pernah saya gunakan.

Sebagian besar sistem yang pernah saya gunakan hanya memiliki satu konfigurasi lingkungan runtime produksi. Mungkin ada konfigurasi lain untuk pengujian dan sebagainya.

Saya akan mengatakan bahwa autowiring penuh adalah ruby-on-rails of spring: Ini mencakup gagasan bahwa ada pola penggunaan normal dan umum yang mengikuti kebanyakan kasus penggunaan. Dengan konfigurasi XML Anda mengizinkan banyak penggunaan konfigurasi konsisten / tidak konsisten yang mungkin / mungkin tidak dimaksudkan. Saya telah melihat begitu banyak konfigurasi xml berlebihan dengan ketidakkonsistenan - apakah itu bisa di refactored bersama dengan kode? Saya pikir tidak. Apakah variasi itu ada karena suatu alasan? Biasanya tidak.

Kami hampir tidak menggunakan kualifikasi dalam konfigurasi kami, dan menemukan cara lain untuk menyelesaikan situasi ini. Ini adalah "kerugian" jelas yang kami temui: Kami telah sedikit mengubah cara kode kami agar berinteraksi lebih lancar dengan autowiring: Repositori pelanggan tidak lagi mengimplementasikan Repository<Customer>antarmuka umum tetapi kami membuat antarmuka CustomerRepositoryyang diperluas Repository<Customer>. Terkadang ada juga satu atau dua trik dalam hal subclassing. Tapi itu biasanya hanya mengarahkan kita ke arah pengetikan yang lebih kuat, yang saya temukan hampir selalu merupakan solusi yang lebih baik.

Tapi ya, Anda mengikat gaya DI tertentu yang kebanyakan dilakukan musim semi. Kami bahkan tidak membuat setter publik untuk dependensi lagi (Jadi Anda bisa berargumen bahwa kami +1 di departemen enkapsulasi / informasi) Kami masih memiliki beberapa xml dalam sistem kami, tetapi xml pada dasarnya hanya berisi anomali. Autowiring penuh terintegrasi dengan baik dengan xml.

Satu-satunya hal yang kita butuhkan sekarang adalah untuk @Component, @Autowireddan sisanya untuk dimasukkan dalam JSR (seperti JSR-250 ), jadi kita tidak harus mengikat dengan musim semi. Ini adalah cara terjadinya hal-hal di masa lalu ( java.util.concurrenthal - hal muncul dalam pikiran), jadi saya tidak akan sepenuhnya terkejut jika ini terjadi lagi.

krosenvold
sumber
5
The javax.annotation / javax.inject didukung oleh spring sehingga Anda tidak harus memiliki ketergantungan kode pada Spring.
Michael Wiles
26

Bagi saya di sini adalah apa yang saya suka / tidak suka tentang Spring dan auto-wiring.

Pro:

  • Pengkabelan otomatis menghilangkan konfigurasi XML yang buruk.
  • Jauh lebih mudah untuk menggunakan anotasi yang memungkinkan Anda untuk menyuntikkan langsung menggunakan bidang, metode penyetel, atau konstruktor. Juga memungkinkan Anda untuk membuat anotasi dan 'memenuhi syarat' kacang yang disuntikkan.

Cons:

  • Menggunakan pengkabelan otomatis dan anotasi membuat Anda bergantung pada pustaka Spring di mana dengan konfigurasi XML Anda bisa memilih untuk menjalankan dengan atau tanpa Spring. Seperti yang Anda katakan, Anda menjadi terikat pada kerangka DI.
  • Pada saat yang sama saya suka bisa 'memenuhi syarat' kacang, bagi saya ini membuat kode benar-benar berantakan. Jika Anda perlu menyuntikkan kacang yang sama di beberapa tempat, saya telah melihat nama string yang sama berulang. Bagi saya ini sepertinya memiliki potensi kesalahan.

Saya sudah mulai menggunakan auto-wiring hampir secara eksklusif di tempat kerja karena kami sangat bergantung pada integrasi Spring sehingga masalah ketergantungan diperdebatkan. Saya bekerja pada proyek Spring MVC yang menggunakan kabel otomatis secara ekstensif dan agak sulit untuk membungkus kepala saya.

Saya pikir auto-wiring adalah rasa yang didapat, setelah Anda terbiasa, Anda menyadari betapa kuat, mudah, dan jauh lebih sedikit sakit kepala dibandingkan dengan konfigurasi XML.

Jared Knipp
sumber
3
konfigurasi xml menjadi jauh lebih tidak jahat jika Anda menggunakan Springsource Tool Suite gratis, yang dilengkapi pelengkapan otomatis, grafik kacang, dll.
Sean Patrick Floyd
Saya sangat setuju dengan Anda tentang pemasangan kabel otomatis yang berantakan dan bergantung pada perpustakaan musim semi! Saya tidak pernah menggunakan konfigurasi XML dan berpikir saya mungkin harus menuju jalan itu?
James111
15

Kami beralih dari @ Autowire kembali ke konfigurasi XML di proyek besar kami. Masalahnya adalah kinerja bootstrap yang sangat rendah. Pemindai autowiring memuat semua kelas dari classpath pencarian autowiring, jadi, banyak kelas dimuat dengan penuh semangat selama inisialisasi Spring.

Masterhard
sumber
1
Saya telah menemukan bahwa javaconfig bahkan mungkin menjadi solusi yang lebih baik untuk memulai konteks parsial, yang merupakan kemenangan besar. Tetapi Anda dapat menggabungkan ini dengan mudah dengan menggunakan @ Autowired / @ Suntikkan pada konstruktor (dengan kata lain, beralih ke injeksi konstruktor).
krosenvold
6

Ada sangat sedikit diskusi tentang pergantian lingkungan. Sebagian besar proyek yang saya kerjakan merupakan masalah nyata untuk menyuntikkan dependensi tergantung pada lingkungan yang sedang kami kerjakan. Dengan konfigurasi xml cukup mudah dengan Spring EL, dan saya tidak mengetahui adanya solusi yang bagus dengan anotasi. Saya baru saja menemukan satu:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

Itu harus bekerja, tetapi bukan solusi yang bagus.

BTakacs
sumber
Saya membuka utas terpisah tentang ini, dan ada solusi dengan Spring @Profilesdan @Configuration: blog.springsource.org/2011/02/14/… Lihat juga utas lainnya: stackoverflow.com/questions/13490393/…
BTakacs
4

Saya telah beralih ke @ Autowire. Mempertahankan konfigurasi XML pada apa pun selain proyek kecil menjadi tugas dalam haknya sendiri dan pemahaman cepat terdegradasi.

IntelliJ memberikan dukungan yang baik (tidak sempurna) untuk anotasi Spring.

Paul McKenzie
sumber
3

Pandangan saya tentang subjek ini adalah, konfigurasi xml mengurangi kejelasan kode, terutama dalam sistem besar.

Anotasi seperti @Component membuat segalanya lebih buruk. Ini mengarahkan pengembang untuk membuat objek bisa berubah, karena dependensi tidak dapat dibuat final lagi, mengingat bahwa konstruktor default perlu disediakan. Ketergantungan perlu disuntikkan melalui setter publik, atau tidak terkontrol melalui @ Autowired. [Injeksi ketergantungan yang lebih buruk lagi dikompromikan dengan kelas-kelas yang instantiate dependensi mereka, saya masih melihat ini dalam kode yang baru ditulis!]. Maksud saya yang tidak terkendali, dalam sistem besar, ketika banyak implementasi (atau anak-anak) dari tipe tersebut tersedia, semakin banyak yang terlibat untuk memahami implementasi mana yang @Autowired, kompleksitas yang membuat investigasi bug jauh lebih sulit. Ini juga berarti bahwa, konon Anda memiliki profil untuk lingkungan pengujian dan lainnya untuk produksi,

Saya tetap di jalan tengah di mana saya mendeklarasikan kelas konfigurasi saya (es), (konfigurasi Spring berbasis java menggunakan @Configuration)

Saya mendeklarasikan semua kacang saya secara eksplisit di kelas konfigurasi (es). Saya hanya menggunakan @Autowired di kelas konfigurasi, tujuannya adalah untuk membatasi ketergantungan pada Spring ke kelas konfigurasi

@Configuration berada dalam paket tertentu, itulah satu-satunya tempat di mana pemindaian pegas berjalan. (Itu mempercepat waktu mulai secara substansial dalam proyek besar)

Saya berusaha untuk membuat semua kelas saya tidak berubah, terutama objek data, JPA, Hibernate dan Spring, serta banyak perpustakaan serialisasi yang tampaknya merusak ini. Saya menjauhi apa pun yang memaksa saya untuk menyediakan setter, atau menghapus kata kunci terakhir dari deklarasi properti saya.

Mengurangi kemungkinan mengubah objek setelah dibuat, secara substansial mengurangi bug dalam sistem besar serta mengurangi waktu untuk menemukan bug ketika ada.

Tampaknya juga memaksa pengembang untuk merancang interaksi antara berbagai bagian sistem dengan lebih baik. Masalah dan bug menjadi kesalahan kompilasi yang semakin banyak, yang mengurangi waktu yang terbuang dan meningkatkan produktivitas.

Charbel
sumber
1

Berikut adalah beberapa pengalaman
Pro

  • Membuatnya lebih mudah untuk dikonfigurasikan karena kita bisa menggunakan anotasi @ Autowire
  • Tidak ingin menggunakan metode setter, jadi kelas akan lebih bersih

Cons

  • Pasangan ketat ke file xml meskipun kami menggunakan DI
  • Sulit untuk menemukan implementasi (Tetapi jika Anda menggunakan id yang baik seperti intellij Anda pasti bisa menyingkirkan ini)

Seperti pengalaman pribadi saya, saya tidak banyak menggunakan penjelasan @ AutoWire tetapi dalam kasus-kasus uji.

Rajith Delantha
sumber
1

Saya sangat suka menulis dengan anotasi, bukan XML. Menurut manual Spring dan versi terakhir, XML dan Annotation mencapai hasil yang sama.

Ini daftar saya

Pro:

  • Hapus baris yang tidak berguna dari xml
  • Sederhanakan kode debug: ketika Anda membuka kelas, Anda dapat membaca apa yang Anda miliki di kelas
  • Lebih cepat berkembang, proyek dengan 400 atau lebih garis XML dapat dibaca?

Cons:

  • Bukan implementasi Java standar, tetapi Anda bisa beralih menggunakan @Inject, yang merupakan Java Standard Api, sehingga bean tetap menjadi Pojo
  • Anda tidak bisa begitu saja menggunakan di mana-mana, koneksi db dan sebagainya, tapi itu hanya pendapat, saya lebih suka punya tempat di mana membaca semua konfigurasi.
Luca Preziati
sumber
0

Untuk pemahaman saya @ Autowired adalah yang terbaik untuk digunakan saat merujuk ke referensi antarmuka dan menggunakan funtions override, tapi saya hanya menemukan masalah dengan ini adalah bahwa kadang-kadang ditugaskan untuk null saat runtime.

Shubham kapoor
sumber