1. 程式人生 > >Spring的IOC分析(二)源碼

Spring的IOC分析(二)源碼

width single def app ali instance exc net classpath

  承接上節繼續,分析Ioc的工作原理,在典型的 IOC 場景中,容器創建了所有對象,並設置必要的屬性將它們連接在一起(同時一個叫DI“依賴註入”或DL“依賴查找”的概念,在C++,java,php以及.net中也是用到過,但是Spring中也把IOC叫做依賴註入,這是找到資料上面是這樣寫的),決定什麽時間 調用方法。從源碼的角度看這個過程是怎樣實現一下幾步:
  • 定位
  • 載入
  • 初始化
  • 註冊
  • 依賴註入使用
  在上章節裏ClassPathXmlApplicationContext這個類  技術分享圖片
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分析(二)源碼