Kako koristiti Spring FactoryBean?

1. Pregled

U posudi za proljetni grah postoje dvije vrste graha: obični grah i tvornički grah. Spring koristi prvu izravno, dok druga može sama proizvesti objekte kojima upravlja okvir.

I, jednostavno rečeno, primjenom možemo izgraditi tvornički grah org.springframework.beans.factory.FactoryBean sučelje.

2. Osnove tvorničkog graha

2.1. Provesti a FactoryBean

Pogledajmo FactoryBean sučelje prvo:

javno sučelje FactoryBean {T getObject () baca iznimku; Klasa getObjectType (); boolean isSingleton (); }

Razmotrimo tri metode:

  • getObject () - vraća objekt koji je proizvela tvornica, a to je objekt koji će koristiti Spring spremnik
  • getObjectType () - vraća vrstu objekta koji ovo FactoryBean proizvodi
  • isSingleton () - označava da li je objekt proizveden ovim FactoryBean je singleton

Sada, provedimo primjer FactoryBean. Provest ćemo a ToolFactory koja proizvodi predmete tipa Alat:

alat za javnu klasu {private int id; // standardni konstruktori, getteri i postavljači}

The ToolFactory sebe:

javna klasa ToolFactory implementira FactoryBean {private int factoryId; private int toolId; @Override public Tool getObject () baca iznimku {return new Tool (toolId); } @Override javna klasa getObjectType () {return Tool.class; } @Override javni boolean isSingleton () {return false; } // standardni postavljači i dobivači}

Kao što vidimo, ToolFactory je FactoryBean, koji mogu proizvesti Alat predmeta.

2.2. Koristiti FactoryBean S konfiguracijom temeljenom na XML-u

Pogledajmo sada kako koristiti naš ToolFactory.

Započet ćemo s izradom alata s XML-zasnovanom konfiguracijom - factorybean-spring-ctx.xml:

Dalje, možemo testirati je li Alat objekt je pravilno ubrizgan:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (locations = {"classpath: factorybean-spring-ctx.xml"}) javna klasa FactoryBeanXmlConfigTest {@Autowired privatni alatni alat; @Test public void testConstructWorkerByXml () {assertThat (tool.getId (), jednakTo (1)); }}

Rezultati testa pokazuju da uspijevamo ubrizgati objekt alata koji je proizveo ToolFactory sa svojstvima koja smo konfigurirali u factorybean-spring-ctx.xml.

Rezultat testa također pokazuje da spremnik Spring koristi objekt koji je proizveo FactoryBean umjesto sebe za injekciju ovisnosti.

Iako spremnik Spring koristi FactoryBean‘S getObject () povratnu vrijednost metode kao grah, također možete koristiti FactoryBean sebe.

Za pristup FactoryBean, samo trebate dodati "&" prije naziva zrna.

Pokušajmo nabaviti tvornički grah i njegovo tvorničkiId svojstvo:

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

2.3. Koristiti FactoryBean S Javnom konfiguracijom

Koristiti FactoryBean s konfiguracijom temeljenom na Javi malo je drugačija s konfiguracijom na temelju XML-a, morate nazvati FactoryBean‘S getObject () metoda eksplicitno.

Pretvorimo primjer u prethodnom pododjeljku u primjer konfiguracije zasnovan na Javi:

@Configuration javna klasa FactoryBeanAppConfig {@Bean (name = "tool") public ToolFactory toolFactory () {FactoryFactory factory = new ToolFactory (); factory.setFactoryId (7070); factory.setToolId (2); tvornica za povratak; } @Bean public Tool Tool () baca iznimku {return toolFactory (). GetObject (); }}

Zatim testiramo je li Alat objekt je pravilno ubrizgan:

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

Rezultat testa pokazuje sličan učinak kao i prethodni test konfiguracije zasnovan na XML-u.

3. Načini inicijalizacije

Ponekad morate izvršiti neke operacije nakon FactoryBean je postavljen, ali prije getObject () poziva se metoda, poput provjere svojstava.

To možete postići primjenom InitializingBean sučelje ili pomoću @PostConstruct bilješka.

Više pojedinosti o korištenju ova dva rješenja predstavljeno je u drugom članku: Vodič za pokretanje logike pri pokretanju u proljeće.

4. AbstractFactoryBean

Proljeće pruža AbstractFactoryBean kao jednostavni predložak superklase za FactoryBean implementacije. S ovom osnovnom klasom sada možemo jednostavnije implementirati tvornički grah koji stvara singleton ili prototipni objekt.

Provedimo a SingleToolFactory i a NonSingleToolFactory pokazati kako se koristi AbstractFactoryBean i za singleton i za prototip tipa:

javna klasa SingleToolFactory proširuje AbstractFactoryBean {private int factoryId; private int toolId; @Override public Class getObjectType () {return Tool.class; } @Override zaštićeni alat createInstance () baca iznimku {return new Tool (toolId); } // standardni postavljači i dobivači}

A sada implementacija nesingtona:

javna klasa NonSingleToolFactory proširuje AbstractFactoryBean {private int factoryId; private int toolId; public NonSingleToolFactory () {setSingleton (false); } @Override javna klasa getObjectType () {return Tool.class; } @Override zaštićeni alat createInstance () baca iznimku {return new Tool (toolId); } // standardni postavljači i dobivači}

Također, XML konfiguracija za ove tvorničke grah:

Sada možemo testirati je li Radnik svojstva objekata ubrizgavaju se kako očekujemo:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (locations = {"classpath: factorybean-abstract-spring-ctx.xml"}) javna klasa AbstractFactoryBeanTest {@Resource (name = "singleTool") privatni alat Tool1; @Resource (name = "singleTool") privatni alat Tool2; @Resource (name = "nonSingleTool") privatni alat Tool3; @Resource (name = "nonSingleTool") privatni alat Tool4; @Test public void testSingleToolFactory () {assertThat (tool1.getId (), jednakTo (1)); assertTrue (alat1 == alat2); } @Test public void testNonSingleToolFactory () {assertThat (tool3.getId (), jednakTo (2)); assertThat (tool4.getId (), jednakTo (2)); assertTrue (alat3! = alat4); }}

Kao što možemo vidjeti iz testova, SingleToolFactory proizvodi singleton objekt, a NonSingleToolFactory proizvodi prototipni objekt.

Imajte na umu da nema potrebe za postavljanjem singleton svojstva SingleToolFactory jer, u SažetakTvornica, zadana vrijednost svojstva singleton je pravi.

5. Zaključak

Korištenje a FactoryBean može biti dobra praksa za inkapsuliranje složene konstrukcijske logike ili olakšavanje konfiguriranja objekata koji se mogu konfigurirati u proljeće.

Tako smo u ovom članku predstavili osnove kako implementirati naš FactoryBean, kako ga koristiti u XML i Java konfiguraciji, te nekim drugim raznim aspektima FactoryBean, kao što je inicijalizacija FactoryBean i AbstractFactoryBean.

Kao i uvijek, kompletan je izvor gotov na GitHubu.