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();
    }
}

运行结果;
在这里插入图片描述
可以看到两个实现类复用了抽象类的固有代码,且根据自己的情况有了不同的实现。

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