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
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管理的類的對象,并且都是同一個對象。
兩種方式的加載模式
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方法的對象(延遲加載/懶加載)
再運作test2: 配置在xml裡面的bean都被建立了(迫切加載)