Spring源碼(3)-Spring中的ApplicationContext

前面提到的BeanFactory接口和起相關的 二級三級實現,只是簡單容器,我們平時 用到的最多的還是ApplicationContext接口的實現類.BeanFactory面向Spring自身,而後者是面向Spring的使用者。

ApplicationContext

ApplicationContext繼承的幾口有很多,因此功能也就更多。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

EnvironmentCapable
該接口僅僅定義了一個Environment getEnvironment();的方法,返回一個Environment對象,主要是用來描述啓動時一些配置信息。

ListableBeanFactory

第二篇文章已經分析過,提供了一列表的方式管理Bean

HierarchicalBeanFactory

支持多層次的容器,來對每一層容器的Bean進行管理。

ResourcePatternResolver

public interface ResourcePatternResolver extends ResourceLoader 

該接口繼承了 ResourceLoader ,可以用來加載資源文件。

MessageSource

管理一些Message,實現國際化相關的功能。

ApplicationEventPublisher

繼承該接口,承諾擁有事件發佈的能力。
在這裏插入圖片描述
容器在啓動的時候,會給自己註冊一些監聽器,監聽容器發佈的時間。

ApplicationContext是一個傳統的基於XML配置的經典容器,有以下幾個常用 實現。
在這裏插入圖片描述
1.FileSystemXmlApplicationContext
從文件系統中加載配置。
2.ClassPathXmlApplicationContext
從classpath加載配置文件。

然而現在流行的是註解的方式進行配置。所以還有以下幾種。
1.AnnotationConfigApplicationContext
2.AnnotationConfigServletWebApplicationContext
3.AnnotationConfigApplicationContext

第一個是Spring的實現,2和3 在SpringBoot的Boot的boot模塊。

ConfigurableApplicationContext

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable 

回頭再看ApplicationContext,發現這個接口是隻讀的,意思就是這個接口只提供了只讀的能力。
在這裏插入圖片描述
ConfigurableApplicationContext 繼承了 ApplicationContext,並拓展了set方法。
在這裏插入圖片描述

Lifecycle接口的方法用於對容器聲明週期的管理。
Closeable用於關閉容器的時候方法相關的資源。
而ConfigurableApplicationContext新增的其他兩個方法:refresh用於啓動和刷新,close用於關閉應用上下文。

AbstractApplicationContext

在這裏插入圖片描述
該抽像類實現了大部分的通用方法,以供子類使用。
主要是容器工廠的處理,事件的發送廣播 ,監聽器的註冊,容器初始化操作 refresh方法,getBean方法的實現。大部分方法實現了,將一些容易變動的方法邏輯代理給他的成員變量來實現,最後使用模板方法模式讓子類爲父類提供一些方法的支持,或者替換。從而滿足開閉原則。

模板方法模式

模板方法模式是基於繼承的,主要會準備一個抽象類,將部分邏輯一具體的方法實現,然後定義一個模板結構,將剩下的具體內容延遲到子類去實現。比如聲明抽象方法迫使子類去實現。
特點 :
1.複用不易變動的代碼,將會變動的實現邏輯向下沉到子類去實現
2.反向控制 ,通過父類調用子類的操作,通過子類的具體實現,擴展出不同的行爲,以此來實現 反向控制。

一般涉及到四種方法:
1.模板方法 -定義了整個方法需要操作的骨架。骨架中可能有具體方法,鉤子方法,抽象方法。
2.具體方法 -一些確定不變的邏輯直接父類實現
3.鉤子方法-一個空的實現的非抽象方法。在特定時候由子類確定是否實現。
4.抽象方法-迫使子類必須實現的方法。易變動的邏輯 代碼。
例子

比如去KTV唱歌 ,有幾個固定流程。
打開機器,點歌,額外消費,結賬。

package com.fuyouj.model.template;

public abstract class KTVRoom {
//模板方法 
    public void procedure(){
        //打開設備 固定方法
        openDevice();
        //點歌 抽象的方法
        oderSong();
        //額外消費 可選方法
        orderExtra();
        //結賬
        pay();
    }

    private void pay() {
        System.out.println("結賬");
    }

    protected void orderExtra() {
    }

    protected abstract void oderSong();

    private void openDevice() {
        System.out.println("打開唱歌的設備");
    }

}

然後中國人定製了 額外消費。

package com.fuyouj.model.template;

public class RoomForChinese extends KTVRoom {
    @Override
    protected void oderSong() {
        System.out.println("點了中文歌曲");
    }

    @Override
    protected void orderExtra() {
        System.out.println("額外消費");
    }
}

美國人不會點東西,只是唱了歌。

package com.fuyouj.model.template;

public class RoomForAmerican extends KTVRoom {
    @Override
    protected void oderSong() {
        System.out.println("點了英文歌曲");
    }
}

可以看到,由於額外消費不是抽象方法,所以子類可以不用實現。
測試demo

package com.fuyouj.model.template;

public class TemplateDemo {
    public static void main(String[] args) {
        KTVRoom ch = new RoomForChinese();
        KTVRoom us = new RoomForAmerican();
        ch.procedure();
        System.out.println("------");
        us.procedure();
    }
}

運行結果;
在這裏插入圖片描述
可以看到兩個實現類複用了抽象類的固有代碼,且根據自己的情況有了不同的實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章