平常在使用的 Spring 的過程中,我想大家應該用到的都是 ApplicationContext 用來讀取配置檔案,然後啟動 Spring 容器。但是,我們使用過程中,肯定也知道存在 Beanfactory 的存在。那麼我們為什麼都是使用 ApplicationContext,而非 Beanfactory 的那?
BeanFactory 獲取 Bean
現在寫個用 BeanFactory 來獲取定義的 bean 程式。
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
DemoServiceImpl demo = (DemoServiceImpl) beanFactory.getBean("demo");
複製程式碼
現在我們對比用 ApplicationContext 寫一個獲取 bean 的程式。
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DemoService demo = (DemoService) ctx.getBean("demo");
複製程式碼
從上面兩個程式對比可以看出,使用 Beanfactory 來獲取 Bean ,我們還額外實現相關類。這些類我們使用 ApplicationContext 根本無需實現。那麼為什麼是這樣的那?接下去我們檢視 Spring 相關的原始碼。
Spring 原始碼
上面兩個程式我們看出 ApplicationContext 與 BeanFactory 都存在 getBean 這個核心方法。這個時候自然想到。這兩個類是否實現了相同的介面。使用 Idea 類圖功能,得到了下面了關係圖。
從這個圖中我們清晰看出 ApplicationContext 繼承 BeanFactory,自然的 ApplicationContext 就擁有了 BeanFactory 的相關方法了。然後再看其實現類相關程式碼,畫出下面一張類圖。
從這張類圖可以看出,AbstractRefreshableApplicationContext 存在的 Beanfactory 屬性,我們再檢視 ApplicationContext getBean 方法實際上最後委託 BeanFactory 的 getBean 方法。
綜上,我們可以看出 Beanfactory 是 Spring 基礎類,構造很多 Bean 相關的方法。然後 ApplicationContext 繼承了 Beanfactory,封裝了很多獲取 Bean 細節方法,再擴充套件其他方法。這樣我們使用者根本無需考慮相關細節,拿來就可以使用。下面圖展示了兩者相關功能區別。
兩者比較看出,Beanfactory 其實只有基本只有跟 Bean 相關的功能。所以在實際開發中,我們使用 ApplicationContext 就可以使用相關 Spring 功能。如果使用 Beanfactory 其實也可以也實現這些功能,但是這個時候我們就需要知道其中很多相關細節。作為一個框架而言,其自然做到是開箱即用,而無需讓使用者考慮其內部相關細節。所以 Spring 做了相關封裝,最後成了我們經常使用的 ApplicationContext。