天天看點

ApplicationContext與BeanFactory的差別

作者:小彭思考

ApplicationContext與BeanFactory

spring是一個容器架構,把一個類交給spring容器管理,包括了建立對象、儲存對象、對象的初始化和銷毀。 IOC:Inverse of control - 控制反轉;将對象建立的權利和依賴關系的維護【給字段指派】交給Spring去管理。

簡單來說:spring容器就是一個管家,專門管理對象(Spring中管理的對象稱之為bean)。我們需要先建立一個”管家對象“,可以是ApplicationContext或者BeanFactory。

BeanFactory

BeanFactory是IOC容器的核心接口,spring容器中有BeanFactory的具體實作:DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等;比如XMLBeanFactory就是一種典型的BeanFactory。

注意:

Spring要幫我們建立對象,我們把建立的對象都叫做bean,但是咱們得寫配置告訴Spring,去幫咱們建立哪一個對象 (注冊)。

bean:配置一個bean對象

id:這個bean的唯一名稱

class:要配置的對象的類型(必須是全限定名)

Spring是通過反射去建立這個對象的。

在配置檔案中将這個Java類交給Spring管理。在applicationContext.xml中配置

<!-- 這個類現在交給spring管理了-->
<bean id = "hello" class= "cn.itsource._01hello.SpringHello">
</bean>           
//使用XMLBeanFactory擷取Spring容器中配置或注冊的Bean對象
	@Test
	public void test() {
		 //讀取核心的配置檔案
		 ClassPathResource resource = new ClassPathResource("ApplicationContext.xml");
		 //拿到核心對象
		 BeanFactory BeanFactory = new XmlBeanFactory(resource);
		 //根據xml配置的id獲得bean對象
		//根據配置檔案的id擷取對象,spring不知道類型,需要強轉
		 SpringHello bean = (SpringHello) BeanFactory.getBean("hello");
		 System.out.println(bean);
		//根據配置檔案的類型擷取對象
		 SpringHello bean2 = BeanFactory.getBean(SpringHello.class);
		 System.out.println(bean2);
		//根據配置檔案的id,和類型擷取對象
		 SpringHello bean3 = BeanFactory.getBean("hello",SpringHello.class);
		 System.out.println(bean3);
	}           

測試運作可以看出:三種方法都可以拿到被spring管理的類的對象,并且都是同一個對象。

ApplicationContext與BeanFactory的差別

ApplicationContext

ApplicationContext的中文意思是"應用程式上下文",它繼承自BeanFactory接口,除了包含BeanFactory的所有功能之外,在國際化支援、資源通路(如URL和檔案)、事件傳播等方面進行了良好的支援(功能更強大)。相對于XmlBeanFactory更多使用ApplicationContext。

@Test
	public void test2() {
		//1.獲到核心配置檔案  applicationContext.xml
		//2.拿到核心對象(相當于啟動了架構)
		//ClassPathXmlApplicationContext
		// 注意:ApplicationContext就是一個Bean工廠,且功能強大得多
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
		//根據配置檔案的id擷取對象,spring不知道類型,需要強轉
		SpringHello bean = (SpringHello) context.getBean("hello");
		System.out.println(bean);
		SpringHello bean2 = context.getBean("hello",SpringHello.class);
		System.out.println(bean2);
		//根據配置檔案的類型擷取對象
		SpringHello bean3 = context.getBean(SpringHello.class);
		System.out.println(bean3);
	}           

測試運作可以看出:三種方法都可以拿到被spring管理的類的對象,并且都是同一個對象。

ApplicationContext與BeanFactory的差別

兩種方式的加載模式

BeanFactroy采用的是延遲加載形式來注入Bean的,即隻有在使用到某個Bean時(調用getBean()),才對該Bean進行加載執行個體化,而ApplicationContext則相反,它是在容器啟動時,一次性建立了所有的Bean。這樣,在容器啟動時,我們就可以發現Spring中存在的配置錯誤。

相對于基本的BeanFactory,ApplicationContext

唯一的不足是占用記憶體空間。當應用程式配置Bean較多時,程式啟動較慢。

舉個例子

在applicationContext.xml我們多配置一個bean。

<bean id = "hello" class= "cn.itsource._01hello.SpringHello">
	</bean>
	
	//測試兩種加載的差別
	 <bean id="test1" class="cn.itsource._02di.Tets1">
	 </bean>           

在測試類的無參構造裡面列印一句話,如果顯示出來,代表調用了無參構造建立對象

//這是測試類,已經配置到xml裡面了
public class Tets1 {
	public Tets1() {
		super();
		System.out.println("我也被建立了");
	}           

然後先運作test:用XmlBeanFactory的方式: 這種方式隻建立了我們調用getBean方法的對象(延遲加載/懶加載)

ApplicationContext與BeanFactory的差別

再運作test2: 配置在xml裡面的bean都被建立了(迫切加載)

繼續閱讀