Bagaimana cara menggunakan Spring FactoryBean?

1. Gambaran keseluruhan

Terdapat dua jenis kacang dalam bekas kacang Spring: kacang biasa dan kacang kilang. Spring menggunakan yang pertama secara langsung, sedangkan yang terakhir dapat menghasilkan objek sendiri, yang dikendalikan oleh kerangka.

Sederhananya, kita boleh membina kacang kilang dengan melaksanakan antara muka org.springframework.beans.factory.FactoryBean .

2. Asas Kacang Kilang

2.1. Laksanakan FactoryBean

Mari lihat dahulu antara muka FactoryBean :

public interface FactoryBean { T getObject() throws Exception; Class getObjectType(); boolean isSingleton(); }

Mari kita bincangkan tiga kaedah:

  • getObject () - mengembalikan objek yang dihasilkan oleh kilang, dan ini adalah objek yang akan digunakan oleh bekas Spring
  • getObjectType () - mengembalikan jenis objek yang dihasilkan oleh FactoryBean ini
  • isSingleton () - menunjukkan jika objek yang dihasilkan oleh FactoryBean ini adalah singleton

Sekarang, mari kita laksanakan contoh FactoryBean . Kami akan melaksanakan ToolFactory yang menghasilkan objek dari jenis Tool :

public class Tool { private int id; // standard constructors, getters and setters }

The ToolFactory sendiri:

public class ToolFactory implements FactoryBean { private int factoryId; private int toolId; @Override public Tool getObject() throws Exception { return new Tool(toolId); } @Override public Class getObjectType() { return Tool.class; } @Override public boolean isSingleton() { return false; } // standard setters and getters }

Seperti yang kita lihat, ToolFactory adalah FactoryBean , yang dapat menghasilkan objek Tool .

2.2. Gunakan Configuration berasaskan XML FactoryBean

Sekarang mari kita lihat cara menggunakan ToolFactory kami .

Kami akan mula membina alat dengan konfigurasi berasaskan XML - factorybean-spring-ctx.xml :

Seterusnya, kita dapat menguji apakah objek Alat disuntik dengan betul:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:factorybean-spring-ctx.xml" }) public class FactoryBeanXmlConfigTest { @Autowired private Tool tool; @Test public void testConstructWorkerByXml() { assertThat(tool.getId(), equalTo(1)); } }

Hasil ujian menunjukkan kami berjaya menyuntik objek alat yang dihasilkan oleh ToolFactory dengan sifat yang kami konfigurasikan di factorybean-spring-ctx.xml .

Hasil ujian juga menunjukkan bahawa bekas Spring menggunakan objek yang dihasilkan oleh FactoryBean dan bukannya dirinya sendiri untuk suntikan kebergantungan.

Walaupun bekas Spring menggunakan FactoryBean 's getObject () nilai pulangan method sebagai kacang, anda juga boleh menggunakan FactoryBean sendiri.

Untuk mengakses FactoryBean , anda hanya perlu menambahkan "&" sebelum nama kacang.

Mari cuba dapatkan kacang kilang dan harta kilangnya :

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:factorybean-spring-ctx.xml" }) public class FactoryBeanXmlConfigTest { @Resource(name = "&tool") private ToolFactory toolFactory; @Test public void testConstructWorkerByXml() { assertThat(toolFactory.getFactoryId(), equalTo(9090)); } }

2.3. Gunakan FactoryBean With Configuration berasaskan Java

Penggunaan FactoryBean dengan konfigurasi berasaskan Java adalah sedikit berbeza dengan konfigurasi berasaskan XML, anda perlu untuk memanggil FactoryBean 's getObject () kaedah jelas.

Mari ubah contoh dalam subseksyen sebelumnya menjadi contoh konfigurasi berasaskan Java:

@Configuration public class FactoryBeanAppConfig { @Bean(name = "tool") public ToolFactory toolFactory() { ToolFactory factory = new ToolFactory(); factory.setFactoryId(7070); factory.setToolId(2); return factory; } @Bean public Tool tool() throws Exception { return toolFactory().getObject(); } }

Kemudian, kami menguji apakah objek Alat disuntik dengan betul:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = FactoryBeanAppConfig.class) public class FactoryBeanJavaConfigTest { @Autowired private Tool tool; @Resource(name = "&tool") private ToolFactory toolFactory; @Test public void testConstructWorkerByJava() { assertThat(tool.getId(), equalTo(2)); assertThat(toolFactory.getFactoryId(), equalTo(7070)); } }

Hasil ujian menunjukkan kesan yang serupa dengan ujian konfigurasi berasaskan XML sebelumnya.

3. Cara Memulakan

Kadang kala anda perlu melakukan beberapa operasi setelah FactoryBean ditetapkan tetapi sebelum kaedah getObject () dipanggil, seperti pemeriksaan sifat.

Anda boleh mencapainya dengan menerapkan antara muka InitializingBean atau menggunakan anotasi @PostConstruct .

Maklumat lebih terperinci mengenai penggunaan kedua-dua penyelesaian ini telah diperkenalkan dalam artikel lain: Panduan Menjalankan Logik pada Permulaan pada Musim Bunga.

4. AbstrakFactoryBean

Spring menyediakan AbstractFactoryBean sebagai superclass templat ringkas untuk pelaksanaan FactoryBean . Dengan kelas asas ini, kita sekarang dapat dengan lebih mudah menerapkan kacang kilang yang membuat singleton atau objek prototaip.

Mari kita laksanakan SingleToolFactory dan NonSingleToolFactory untuk menunjukkan cara menggunakan AbstractFactoryBean untuk jenis tunggal dan prototaip:

public class SingleToolFactory extends AbstractFactoryBean { private int factoryId; private int toolId; @Override public Class getObjectType() { return Tool.class; } @Override protected Tool createInstance() throws Exception { return new Tool(toolId); } // standard setters and getters }

Dan sekarang pelaksanaan nonsingleton:

public class NonSingleToolFactory extends AbstractFactoryBean { private int factoryId; private int toolId; public NonSingleToolFactory() { setSingleton(false); } @Override public Class getObjectType() { return Tool.class; } @Override protected Tool createInstance() throws Exception { return new Tool(toolId); } // standard setters and getters }

Juga, konfigurasi XML untuk kacang kilang ini:

Sekarang kita boleh menguji sama ada sifat objek Pekerja disuntik seperti yang kita jangkakan:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:factorybean-abstract-spring-ctx.xml" }) public class AbstractFactoryBeanTest { @Resource(name = "singleTool") private Tool tool1; @Resource(name = "singleTool") private Tool tool2; @Resource(name = "nonSingleTool") private Tool tool3; @Resource(name = "nonSingleTool") private Tool tool4; @Test public void testSingleToolFactory() { assertThat(tool1.getId(), equalTo(1)); assertTrue(tool1 == tool2); } @Test public void testNonSingleToolFactory() { assertThat(tool3.getId(), equalTo(2)); assertThat(tool4.getId(), equalTo(2)); assertTrue(tool3 != tool4); } }

Seperti yang dapat kita lihat dari ujian, SingleToolFactory menghasilkan objek tunggal, dan NonSingleToolFactory menghasilkan objek prototaip.

Perhatikan bahawa tidak perlu menetapkan properti singleton di SingleToolFactory kerana, di AbstractFactory , nilai lalai harta singleton adalah benar .

5. Kesimpulan

Menggunakan FactoryBean boleh menjadi amalan yang baik untuk merangkumi logika pembinaan yang kompleks atau membuat konfigurasi objek yang sangat mudah dikonfigurasi lebih mudah pada musim bunga.

Oleh itu, dalam artikel ini, kami memperkenalkan asas bagaimana menerapkan FactoryBean kami , bagaimana menggunakannya dalam konfigurasi berbasis XML dan konfigurasi berbasis Java, dan beberapa aspek lain dari FactoryBean , seperti inisialisasi FactoryBean dan AbstractFactoryBean .

Seperti biasa, sumber lengkap ada di GitHub.