Mengapa saya memerlukan penyetel untuk bidang kabel otomatis/injeksi?

Saya punya kacang:

    <bean id="BasketLogic" class="efco.logic.EfcoBasketLogic" autowire="byType">
        <property name="documentLogic" ref="DocumentLogic" />
        <property name="stateAccess" ref="StateAccess" />
        <property name="contextAccess" ref="ContextAccess" />
    </bean>

  <bean id="EfcoErpService" autowire="byType" class="efco.erp.service.EfcoErpServiceImpl">
    <constructor-arg ref="ErpConnector"/>
  </bean>

documentLogic, stateAccess dan contextAccess adalah kolom di BasketLogicImpl

Dan saya tidak punya <context:component-scan />

EfcoBasketLogic.java:

public class EfcoBasketLogic extends BasketLogicImpl {

        @Inject
        private EfcoErpService erpService;
    ...
    ...
    ...
}

erpService adalah null, kecuali saya menyediakan penyetel. Tapi kenapa? Saya pikir penyetel tidak diperlukan saat pengkabelan otomatis dilakukan? Mungkinkah BasketLogicImpl bertanggung jawab atas hal itu?


person GarfieldKlon    schedule 02.11.2012    source sumber


Jawaban (3)


Anda perlu menggunakan penyetel karena anotasi tidak terdeteksi kecuali pegas diberitahukan melalui <context:component-scan /> atau <context:annotation-config />. Penyetel terdeteksi karena Anda menentukan autowire="byType".

Anda mungkin menemukan pertanyaan dan jawaban ini bermanfaat juga: Kapan menggunakan autowiring di Musim semi

person mrembisz    schedule 02.11.2012
comment
Jika saya melakukannya, masalah baru akan muncul --› Tidak ada kacang unik bertipe [xyz] yang ditentukan: diharapkan kacang tunggal yang cocok tetapi ditemukan 5. Itu disebabkan oleh kacang lain di mana saya secara eksplisit menyuntikkan properti melalui <property name="x" ref="y"> dan ada 5 kacang yang mengimplementasikan antarmuka itu. Properti 'x' memiliki anotasi @Inject. Jadi sepertinya pendefinisian eksplisit tidak mengesampingkan hal-hal yang terhubung secara otomatis? - person GarfieldKlon; 02.11.2012
comment
@Inject akan terselesaikan dengan baik jika hanya ada satu kacang dari tipe tertentu atau yang ditandai sebagai kacang utama. Jika Anda memiliki beberapa kacang jenis itu yang dapat dipertukarkan, Anda perlu menyuntikkan berdasarkan nama menggunakan @Resource atau xml. - person mrembisz; 02.11.2012
comment
Meskipun saya secara eksplisit memasukkan kacang itu melalui <property name="..." ref="..."> ? - person GarfieldKlon; 02.11.2012
comment
Saya sarankan mengajukan pertanyaan lain. Saya telah menjawab pertanyaan awal Anda dan tidak dapat mengetahui apa masalah Anda selanjutnya tanpa penjelasan lebih rinci termasuk beberapa kode atau xml. - person mrembisz; 02.11.2012
comment
Pertanyaan saya adalah mengapa saya harus menulis setter (ketika saya tidak menggunakan pemindaian komponen atau konfigurasi anotasi). - person GarfieldKlon; 02.11.2012
comment
Oke, tapi mengapa saya harus menulis penyetel jika saya menggunakan autowire=byType dan memberi anotasi pada bidang dengan @Inject? Apakah itu memang disengaja, jalan yang harus ditempuh? Maksud saya, saya bisa membuang penyetel jika saya menggunakan konfigurasi anotasi. Jadi ada perbedaan antara itu dan autowire=byType? - person GarfieldKlon; 02.11.2012
comment
Pengkabelan otomatis mendeteksi parameter penyetel dan konstruktor sebagai ketergantungan potensial. Bukan bidang pribadi. Anotasi tidak terlihat kecuali Anda memintanya untuk diperiksa. - person mrembisz; 02.11.2012

Pertama-tama, penggunaan <context:component-scan /> atau <context:annotation-config /> memungkinkan Spring memindai kode Anda untuk mencari kacang yang memenuhi syarat untuk memenuhi dependensi, yang akan sangat meningkatkan kemampuannya untuk menyambungkannya dengan benar, jadi saya sarankan menambahkannya ke file konteks Anda.

Kedua, Anda harus menyadari bahwa @Inject adalah anotasi standar (artinya spesifikasi JSR-330). Tidak apa-apa untuk memadupadankan anotasi Spring dengan anotasi standar, namun perilakunya mungkin berbeda-beda saat melakukannya. @Named biasanya dipasangkan dengan @Inject untuk mencocokkan komponen dengan dependensi (keduanya JSR-330). Lihat referensi ini untuk detailnya, dan lihat Tabel 4.6 untuk komentar penggunaan.

Namun untuk langsung menjawab pertanyaan Anda, "mengapa saya memerlukan penyetel saat tidak menggunakan pemindaian komponen", adalah karena Anda tidak menggunakan pemindaian komponen. Anda meminta Spring untuk memasukkan ketergantungan "byType", tetapi tidak mengizinkan Spring memindai kode Anda untuk komponen bertipe tersebut. Alasan penyetel berfungsi adalah karena jenis argumen penyetel yang dimasukkan dapat ditemukan oleh Spring dalam bytecode yang dikompilasi (yaitu meta-data), sehingga berhasil menyelesaikan permintaan Anda.

person pmhargis    schedule 03.09.2013
comment
FYI: Saat menggunakan ` ‹context:component-scan /› `, pastikan Anda menyetel atribut base-package di akar hierarki kelas tempat kelas kacang dideklarasikan (melalui @Named atau @Autowired). Misalnya: ‹beans› ‹context:component-scan base-package=org.example/› ‹/beans› - person pmhargis; 03.09.2013

Pemahaman saya adalah bahwa konfigurasi XML mengesampingkan konfigurasi anotasi. Fakta bahwa autowire="byType" yang ditentukan mengesampingkan injeksi otomatis, yang mencari keberadaan metode penyetel untuk menyuntikkan ketergantungan.

person kbk    schedule 13.04.2016