Java Academy · Pelajaran

Suntikan Konstruktor dan Kebergantungan Pekeliling

Utamakan suntikan konstruktor untuk kebolehujian, kesan kebergantungan pekeliling dan putuskannya dengan @Lazy.

Pelajaran 4 daripada 413 langkah

Suntikan Konstruktor dan Kebergantungan Pekeliling ialah pelajaran Java Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Java Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Tiga Jenis Suntikan

Spring menyokong suntikan pembina (disyorkan), suntikan medan (@Autowired pada medan), dan suntikan penetap. Suntikan pembina lebih disukai kerana kebolehujiannya dan ketidakbolehubahan.

Suntikan Pembina

Isytiharkan kebergantungan sebagai parameter pembina. Spring menyuntikkannya secara automatik. Jika hanya terdapat satu pembina, @Autowired adalah pilihan (Spring Boot 2.1+).

@Service
public class OrderService {
    private final OrderRepository repo;
    private final EmailService email;
    // @Autowired is optional when there is only one constructor
    public OrderService(OrderRepository repo, EmailService email) {
        this.repo  = repo;
        this.email = email;
    }
}

Mengapa Suntikan Pembina Lebih Disukai

Suntikan pembina: (1) kebergantungan tidak boleh diubah — tidak berubah, (2) kelas sentiasa dimulakan sepenuhnya, (3) tiada kebergantungan Spring dalam ujian unit — hanya panggil new OrderService(mockRepo, mockEmail).

// Unit test — no Spring context needed:
OrderRepository mockRepo  = mock(OrderRepository.class);
EmailService    mockEmail = mock(EmailService.class);
OrderService    service   = new OrderService(mockRepo, mockEmail);
// Test service logic directly

Suntikan Medan (Elakkan)

Suntikan medan dengan @Autowired adalah ringkas tetapi bermasalah: medan tidak boleh ditetapkan sebagai muktamad, komponen tidak dimulakan sepenuhnya selepas pembinaan, dan pengujian unit memerlukan Spring atau pembantu refleksi Mockito.

// Avoid in production code:
@Service
public class UserService {
    @Autowired  // hidden dependency
    private UserRepository repo; // cannot be final
}

Suntikan Penetap untuk Kebergantungan Pilihan

Gunakan suntikan penetap untuk kebergantungan pilihan yang mempunyai nilai lalai yang sesuai — tandakan penetap dengan @Autowired(required = false).

@Service
public class NotificationService {
    private SmsSender smsSender; // optional
    @Autowired(required = false)
    public void setSmsSender(SmsSender s) { this.smsSender = s; }
}

Apakah Kebergantungan Kitaran?

Kebergantungan kitaran berlaku apabila A memerlukan B dan B memerlukan A (secara langsung atau melalui kebergantungan lain). Spring mengesannya pada permulaan dan melontarkan BeanCurrentlyInCreationException.

// CIRCULAR:
@Service class A { A(B b) {} }
@Service class B { B(A a) {} }
// Spring throws: BeanCurrentlyInCreationException: Is there an unresolvable circular reference?

Memutuskan Kebergantungan Kitaran: Refaktor kepada Perkhidmatan Ketiga

Penyelesaian paling bersih ialah mengekstrak logik dikongsi kepada perkhidmatan ketiga yang tidak mempunyai kebergantungan kitaran pada A atau B.

// Before: A <-> B
// After: A -> C, B -> C (no cycle)
@Service class SharedLogic { ... }
@Service class A { A(SharedLogic s) {} }
@Service class B { B(SharedLogic s) {} }

Memutuskan Kebergantungan Kitaran: @Lazy

Anotasikan satu titik suntikan dengan @Lazy. Spring mencipta proksi untuk B dengan segera; B sebenar hanya diwujudkan apabila A memanggil kaedah padanya buat kali pertama.

@Service
public class A {
    private final B b;
    public A(@Lazy B b) { this.b = b; } // breaks the cycle
}

Memutuskan Kebergantungan Kitaran: Carian ApplicationContext

Suntik ApplicationContext ke dalam satu komponen dan cari komponen yang lain secara tertunda melalui context.getBean() — tetapi ini mengurangkan kebolehujian dan kejelasan.

@Service
public class A implements ApplicationContextAware {
    private ApplicationContext ctx;
    public void setApplicationContext(ApplicationContext c) { this.ctx = c; }
    public void doWork() { ctx.getBean(B.class).help(); }
}

Suntikan Penetap untuk Memutuskan Kebergantungan Kitaran

Komponen yang disuntik melalui penetap dicipta terlebih dahulu (pembinaan berjaya), kemudian kebergantungan ditetapkan. Ini membolehkan kebergantungan kitaran dengan mengorbankan kebolehubahan.

@Service
public class A {
    private B b;
    @Autowired public void setB(B b) { this.b = b; } // Spring sets after construction
}

spring.main.allow-circular-references (Spring Boot 2.6+)

Spring Boot 2.6+ tidak membenarkan kebergantungan kitaran secara lalai. Dayakannya secara eksplisit hanya sebagai langkah sementara semasa refaktor: spring.main.allow-circular-references=true.

# application.properties (temporary workaround only):
spring.main.allow-circular-references=true

Semakan Pantas

Mengapakah suntikan pembina lebih disukai berbanding suntikan medan?

Rumusan

Utamakan suntikan pembina: tidak berubah, boleh diuji dan jelas. Elakkan suntikan medan. Gunakan @Lazy atau ekstrak perkhidmatan dikongsi untuk memutuskan kebergantungan kitaran. Spring Boot 2.6+ menandakan rujukan kitaran pada permulaan — anggap ia sebagai amaran reka bentuk.

Percuma untuk bermula

Pelajari Java dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
104
Pelajaran
374

Soalan Lazim

Adakah pelajaran “Suntikan Konstruktor dan Kebergantungan Pekeliling” percuma?

Ya — teks penuh “Suntikan Konstruktor dan Kebergantungan Pekeliling” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Java Academy, tingkat taraf kepada CoddyKit PRO. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Suntikan Konstruktor dan Kebergantungan Pekeliling”?

Utamakan suntikan konstruktor untuk kebolehujian, kesan kebergantungan pekeliling dan putuskannya dengan @Lazy. Anda berlatih Java Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Java Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Java Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Suntikan Konstruktor dan Kebergantungan Pekeliling” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Konfigurasi Automatik dan Starter Spring Boot
  2. Sifat Aplikasi dan Profil
  3. Pendawaian Bean: @Component, @Service, @Repository
  4. Suntikan Konstruktor dan Kebergantungan Pekeliling
← Kembali ke Java Academy