Különbség a BeanFactory és az ApplicationContext között
1. Áttekintés
A Spring Framework két NOB konténert tartalmaz - BeanFactory és ApplicationContext. A BeanFactory a NOB konténerek legalapvetőbb változata, és a ApplicationContext kiterjeszti a BeanFactory.
Ebben a gyors bemutatóban gyakorlati példákkal fogjuk megérteni a két NOB konténer közötti jelentős különbségeket.
2. Lusta betöltés vs lelkes betöltés
BeanFactory igény szerint babot tölt be, míg ApplicationContext indításkor az összes babot betölti. Így, BeanFactory könnyű ahhoz képest ApplicationContext. Értsük meg egy példával.
2.1. Lusta betöltés BeanFactory
Tegyük fel, hogy van egy szinglik bab osztályunk Diák egy módszerrel:
public class Student {public static boolean isBeanInstantiated = hamis; public void postConstruct () {setBeanInstantiated (true); } // szabványos beállítók és szerelők}
Meghatározzuk a postConstruct () módszer, mint a init-módszer miénkben BeanFactory konfigurációs fájl, ioc-container-különbség-példa.xml:
Írjunk egy tesztesetet, amely létrehozza a BeanFactory ellenőrizni, hogy betölti-e a Diák bab:
@Test public void whenBFInitialized_thenStudentNotInitialized () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); BeanFactory gyár = new XmlBeanFactory (res); assertFalse (Student.isBeanInstantiated ()); }
Itt, a Diák az objektum nincs inicializálva. Más szavakkal, csak a BeanFactory inicializálva van. A mi babunkban definiált bab BeanFactory csak akkor töltődik be, ha kifejezetten meghívjuk a getBean () módszer.
Ellenőrizzük az inicializálást Diák bab, ahol manuálisan hívjuk a getBean () módszer:
@Test public void whenBFInitialized_thenStudentInitialized () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); BeanFactory gyár = new XmlBeanFactory (res); Hallgató diák = (Tanuló) gyár.getBean ("hallgató"); assertTrue (Student.isBeanInstantiated ()); }
Itt a Diák babot sikeresen betölt. Ezért a BeanFactory a babot csak akkor tölti be, amikor szükséges.
2.2. Szívesen töltődik ApplicationContext
Most használjuk ApplicationContext helyén BeanFactory.
Csak meghatározzuk ApplicationContext, és azonnal betölti az összes babot egy lelkes rakodási stratégia alkalmazásával:
@Test public void whenAppContInitialized_thenStudentInitialized () {ApplicationContext context = new ClassPathXmlApplicationContext ("ioc-container-erinevus-példa.xml"); assertTrue (Student.isBeanInstantiated ()); }
Itt a Diák az objektum akkor is létrejön, ha még nem hívtuk a getBean () módszer.
ApplicationContext nehéz NOB konténernek tekinthető, mert buzgó rakodási stratégiája az összes babot megrakja indításkor. BeanFactory könnyű ahhoz képest, és hasznos lehet a memória korlátozott rendszerekben. Mindazonáltal, a következő szakaszokban meglátjuk, miért ApplicationContext előnyös a legtöbb felhasználási esetben.
3. Vállalati alkalmazás jellemzői
ApplicationContext fokozza BeanFactory keretrendszer-orientáltabb stílusban, és számos olyan szolgáltatást kínál, amelyek alkalmasak a vállalati alkalmazások számára.
Például azt üzenetküldést biztosít (i18n vagy nemzetközivé válás) funkcionalitás, rendezvény kiadványa funkcionalitás, annotáció-alapú függőségi injekció, és könnyű integráció a Spring AOP funkcióival. Ettől eltekintve a ApplicationContext szinte minden típusú bab hatókört támogat, de a BeanFactory csak két hatókört támogat - Szingli és Prototípus. Ezért mindig előnyösebb használni ApplicationContext komplex vállalati alkalmazások felépítésekor. A ApplicationContext automatikusan regisztrál BeanFactoryPostProcessor és BeanPostProcessor indításkor. Másrészt a BeanFactory nem regisztrálja ezeket az interfészeket automatikusan. Hogy megértsük, írjunk két osztályt. Először is megvan a CustomBeanFactoryPostProcessor osztály, amely végrehajtja a BeanFactoryPostProcessor: Itt felülírtuk a postProcessBeanFactory () módszer a regisztráció ellenőrzésére. Másodszor van egy másik osztályunk, CustomBeanPostProcessor, amely végrehajtja BeanPostProcessor: Itt felülírtuk a postProcessBeforeInitialization () módszer a regisztráció ellenőrzésére. Ezenkívül mindkét osztályt konfiguráltuk a mi ioc-container-különbség-példa.xml konfigurációs fájl: Lássunk egy tesztesetet annak ellenőrzésére, hogy ez a két osztály automatikusan regisztrálásra került-e az indítás során: Mint a tesztünkből kiderül, automatikus regisztráció nem történt meg. Most nézzünk meg egy tesztesetet, amely manuálisan hozzáadja őket a BeanFactory: Itt használtuk a postProcessBeanFactory () módszer a regisztrációhoz CustomBeanFactoryPostProcessor és a addBeanPostProcessor () módszer a regisztrációhoz CustomBeanPostProcessor. Mindketten sikeresen regisztrálnak ebben az esetben. Amint azt korábban megjegyeztük, ApplicationContext automatikusan regisztrálja mindkét osztályt anélkül, hogy további kódot írna. Ellenőrizzük ezt a viselkedést egységteszten: Ahogy látjuk, mindkét osztály automatikus regisztrációja sikeres ebben az esetben. Ebből kifolyólag, mindig tanácsos használni ApplicationContext mert a 2.0 (és újabb) tavasz erősen használja BeanPostProcessor. Érdemes ezt is megjegyezni ha a síkságot használja BeanFactory, akkor az olyan szolgáltatások, mint a tranzakciók és az AOP, nem lépnek életbe (legalábbis anélkül, hogy extra kódsorokat írna). Ez zavart okozhat, mert semmi nem fog rosszul nézni a konfigurációval. Ebben a cikkben a legfontosabb különbségeket láttuk ApplicationContext és BeanFactory gyakorlati példákkal. A ApplicationContext fejlett funkciókkal rendelkezik, köztük több, amely a vállalati alkalmazásokhoz igazodik, míg a BeanFactory csak alapvető funkciókkal rendelkezik. Ezért általában ajánlott a ApplicationContext, és használnunk kellene BeanFactory csak akkor, ha a memóriafogyasztás kritikus. Mint mindig, a cikk kódja elérhető a GitHubon.4. Automatikus regisztráció BeanFactoryPostProcessor és BeanPostProcessor
4.1. Regisztráció itt: BeanFactory
public class CustomBeanFactoryPostProcessor implementálja a BeanFactoryPostProcessor {private static boolean isBeanFactoryPostProcessorRegistered = false; @Override public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) {setBeanFactoryPostProcessorRegistered (true); } // szabványos beállítók és szerelők}
public class CustomBeanPostProcessor implementálja a BeanPostProcessor {private static logikai isBeanPostProcessorRegistered = false; @Orride public Object postProcessBeforeInitialization (Object bean, String beanName) {setBeanPostProcessorRegistered (true); visszatérő bab; } // szabványos beállítók és szerelők}
@Test public void whenBFInitialized_thenBFPProcessorAndBPProcessorNotRegAutomatically () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); ConfigurableListableBeanFactory gyár = new XmlBeanFactory (res); assertFalse (CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered ()); assertFalse (CustomBeanPostProcessor.isBeanPostProcessorRegistered ()); }
@Test public void whenBFPostProcessorAndBPProcessorRegisteredManually_thenReturnTrue () {Resource res = new ClassPathResource ("ioc-container-difference-example.xml"); ConfigurableListableBeanFactory gyár = new XmlBeanFactory (res); CustomBeanFactoryPostProcessor beanFactoryPostProcessor = new CustomBeanFactoryPostProcessor (); beanFactoryPostProcessor.postProcessBeanFactory (gyár); assertTrue (CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered ()); CustomBeanPostProcessor beanPostProcessor = új CustomBeanPostProcessor (); gyár.addBeanPostProcessor (beanPostProcessor); Hallgató diák = (Tanuló) gyár.getBean ("hallgató"); assertTrue (CustomBeanPostProcessor.isBeanPostProcessorRegistered ()); }
4.2. Regisztráció itt: ApplicationContext
@Test public void whenAppContInitialized_thenBFPostProcessorAndBPostProcessorRegisteredAutomatically () {ApplicationContext context = new ClassPathXmlApplicationContext ("ioc-container-difference-example.xml"); assertTrue (CustomBeanFactoryPostProcessor.isBeanFactoryPostProcessorRegistered ()); assertTrue (CustomBeanPostProcessor.isBeanPostProcessorRegistered ()); }
5. Következtetés