@Lotup Anotasi pada Musim Bunga

1. Pengenalan

Dalam tutorial ringkas ini, kita akan melihat sokongan suntikan tahap kaedah Spring, melalui anotasi @Lookup .

2. Mengapa @Lookup ?

Kaedah yang diberi penjelasan dengan @Lookup memberitahu Spring untuk mengembalikan contoh jenis pengembalian kaedah ketika kami memintanya.

Pada asasnya, Spring akan menggantikan kaedah anotasi kami dan menggunakan jenis dan parameter pengembalian kaedah kami sebagai argumen kepada BeanFactory # getBean.

@Lookup berguna untuk:

  • Menyuntik kacang prototaip ke dalam kacang tunggal (serupa dengan Penyedia )
  • Menyuntik kebergantungan secara prosedur

Perhatikan juga bahawa @Lookup adalah Java yang sama dengan kaedah carian elemen XML .

3. Menggunakan @Lookup

3.1. Menyuntikkan kacang prototaip ke dalam kacang Singleton

Sekiranya kita membuat keputusan untuk memiliki prototaip biji kacang, maka kita akan segera menghadapi masalah bagaimana biji bunga tunggal kita akan mengakses biji kacang prototaip ini?

Sekarang, Penyedia tentu sekali jalan, walaupun @Lookup lebih serba boleh dalam beberapa aspek.

Pertama, mari buat prototaip kacang yang kemudian kita suntikan ke dalam kacang tunggal:

@Component @Scope("prototype") public class SchoolNotification { // ... prototype-scoped state }

Dan jika kita membuat kacang tunggal yang menggunakan @Lookup :

@Component public class StudentServices { // ... member variables, etc. @Lookup public SchoolNotification getNotification() { return null; } // ... getters and setters }

Dengan menggunakan @Lookup , kita dapat memperoleh pemberitahuan SchoolNotification melalui singleton bean kami:

@Test public void whenLookupMethodCalled_thenNewInstanceReturned() { // ... initialize context StudentServices first = this.context.getBean(StudentServices.class); StudentServices second = this.context.getBean(StudentServices.class); assertEquals(first, second); assertNotEquals(first.getNotification(), second.getNotification()); }

Perhatikan bahawa dalam StudentServices , kami meninggalkan kaedah getNotification sebagai rintisan.

Ini kerana Spring menggantikan kaedah dengan panggilan ke beanFactory.getBean (StudentNotification.class) , jadi kami boleh membiarkannya kosong.

3.2. Suntikan Ketergantungan Secara Prosedur

Namun, yang lebih hebat lagi ialah @Lookup membolehkan kita memasukkan kebergantungan secara prosedur, sesuatu yang tidak dapat kita lakukan dengan Penyedia .

Mari tingkatkan Pemberitahuan Pelajar dengan beberapa keadaan:

@Component @Scope("prototype") public class SchoolNotification { @Autowired Grader grader; private String name; private Collection marks; public SchoolNotification(String name) { // ... set fields } // ... getters and setters public String addMark(Integer mark) { this.marks.add(mark); return this.grader.grade(this.marks); } }

Sekarang, ini bergantung pada beberapa konteks Spring dan juga konteks tambahan yang akan kami berikan secara prosedur.

Kami kemudian boleh menambahkan kaedah ke StudentServices yang mengambil data pelajar dan meneruskannya:

public abstract class StudentServices { private Map notes = new HashMap(); @Lookup protected abstract SchoolNotification getNotification(String name); public String appendMark(String name, Integer mark) { SchoolNotification notification = notes.computeIfAbsent(name, exists -> getNotification(name))); return notification.addMark(mark); } } 

Pada waktu runtime, Spring akan melaksanakan kaedah dengan cara yang sama, dengan beberapa trik tambahan.

Pertama, perhatikan bahawa ia boleh memanggil konstruktor kompleks serta menyuntikkan kacang Spring yang lain, yang membolehkan kita memperlakukan Pemberitahuan Sekolah sedikit lebih seperti kaedah peka pada Musim Semi.

Ia melakukannya dengan melaksanakan getSchoolNotification dengan panggilan ke beanFactory.getBean (SchoolNotification.class, name) .

Kedua, kadangkala kita boleh menjadikan kaedah @ Lookup- teranotasi abstrak, seperti contoh di atas.

Menggunakan abstrak kelihatan lebih baik daripada rintisan, tetapi kita hanya dapat menggunakannya apabila kita tidak melakukan imbasan komponen atau @ Bean - menguruskan kacang di sekitarnya:

@Test public void whenAbstractGetterMethodInjects_thenNewInstanceReturned() { // ... initialize context StudentServices services = context.getBean(StudentServices.class); assertEquals("PASS", services.appendMark("Alex", 89)); assertEquals("FAIL", services.appendMark("Bethany", 78)); assertEquals("PASS", services.appendMark("Claire", 96)); }

Dengan persediaan ini, kita dapat menambahkan dependensi Spring dan juga dependensi kaedah ke SchoolNotification .

4. Batasan

Walaupun fleksibiliti @Lookup , terdapat beberapa batasan penting:

  • Kaedah @tanda carian, seperti getNotification, mestilah konkrit apabila kelas di sekitarnya, seperti Pelajar, diimbas komponen. Ini kerana pengimbasan komponen melangkau kacang abstrak.
  • Kaedah carian @ anotasi tidak akan berfungsi sama sekali apabila kelas di sekitarnya dikendalikan oleh @Bean.

Dalam keadaan seperti itu, jika kita perlu memasukkan prototaip kacang ke dalam singleton, kita dapat mencari Penyedia sebagai alternatif.

5. Kesimpulan

Dalam artikel ringkas ini, kami belajar bagaimana dan kapan menggunakan anotasi @Lookup Spring , termasuk cara menggunakannya untuk menyuntikkan kacang yang dilindungi prototaip ke dalam kacang tunggal dan bagaimana menggunakannya untuk menyuntik kebergantungan secara prosedur.

Semua kod yang digunakan untuk tutorial ini boleh didapati di Github.