Spring的IOC分析(二)源碼
阿新 • • 發佈:2018-01-24
width single def app ali instance exc net classpath 承接上節繼續,分析Ioc的工作原理,在典型的 IOC 場景中,容器創建了所有對象,並設置必要的屬性將它們連接在一起(同時一個叫DI“依賴註入”或DL“依賴查找”的概念,在C++,java,php以及.net中也是用到過,但是Spring中也把IOC叫做依賴註入,這是找到資料上面是這樣寫的),決定什麽時間 調用方法。從源碼的角度看這個過程是怎樣實現一下幾步:
- 定位
- 載入
- 初始化
- 註冊
- 依賴註入使用
public ClassPathXmlApplicationContext( String[] configLocations,boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent);//這裏是調用的父類的方法 setConfigLocations(configLocations); if (refresh) { refresh(); } }
//創建一個新的AbstractApplicationContext與給定的父上下文中。 public AbstractApplicationContext(@Nullable ApplicationContext parent) {this(); setParent(parent); }
//把parent賦給這個application 上下文
@Override
public void setParent(@Nullable ApplicationContext parent) {
this.parent = parent;
if (parent != null) {
Environment parentEnvironment = parent.getEnvironment();
if (parentEnvironment instanceof ConfigurableEnvironment) {
getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
}
}
}
這裏只是加載application.xml文件的上下文,使我們的Spring的可以讀取到這裏面的所有的配置的bean,接下來的關鍵是,將需要的bean用getBean()的方式去定位拿到。
獲取bean是個結束:下圖表明了獲取bean的方法來自最頂層的接口BeanFactory,所以核心研究這個定義了規範的頂層接口做了做了些什麽,也方便我們的代碼以後的擴張。簡單的下面的這種多種獲取對象bean的面向接口編程方式,就是常見的工廠模式;也即 IOC 容器為開發者管理對象 間的依賴關系提供了很多便利和基礎服務。其實我們知道這些方法就可以滿足我們正在的開發的需要了,但是我們還是想跟著bean的生成過成做一次探索。
//定義了Ioc的基本功能規範 public interface BeanFactory { // 對FactoryBean的轉義,假如,bean的名字被叫做FactoryBean,獲取時會返回一個factory,不是工廠的實例,需要轉義 String FACTORY_BEAN_PREFIX = "&"; //返回一個實例 //根據bean的名字返回一個bean的實例對象 Object getBean(String name) throws BeansException; // 返回一個bean的實例 // 支持泛型的方法是安全的,參數bean的名字和輸入的bean的類型必須一致 <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException; // 返回一個bean的實例 // 輸入一個bean的名字,使用顯式參數創建bean實例時使用的rgs Object getBean(String name, Object... args) throws BeansException; // 返回與給定對象類型匹配的bean實例,如果有的話 <T> T getBean(Class<T> requiredType) throws BeansException; //返回一個實例,該實例可以共享或獨立於指定的bean。 <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; //這個bean工廠是否包含bean定義或外部註冊的單例對象 boolean containsBean(String name); //這個bean是一個共享的單例嗎?返回相同的實例嗎? boolean isSingleton(String name) throws NoSuchBeanDefinitionException; //這個bean是原型嗎? boolean isPrototype(String name) throws NoSuchBeanDefinitionException; //檢查給定名稱的bean是否與指定的類型匹配 boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; //檢查給定名稱的bean是否與指定的類型匹配 boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException; @Nullable Class<?> getType(String name) throws NoSuchBeanDefinitionException; //為給定的bean名稱提供別名,如果有的話。所有這些別名都指向同一個bean,在@link getbean調用中使用。 String[] getAliases(String name); }
對bean的解析是現在開始:描述bean的接口是這個Beandefinition,這是一個比較復雜的一個過程,我也不知道我能不能完全把它說清楚,需要準備一下,我下節中會詳細介紹這裏面的細節實現,容我準備一波。
Spring的IOC分析(二)源碼