J2EE-027 Spring容器源码解析(二)BeanFactory,ApplicationContext体系reader构建过程总结

前言

在上一篇内容中我们讲解了Spirng容器初始化如何加载工厂和如何判断需要加载的bean是否在容器的流程,这篇内容我们解析一下
1.工厂是如何创建的,BeanFactory体系
2.讲解一下我们接受的ApplicationContext接口接收的体系,ApplicationContext


准备工作

这里需要下载插件
PlantUML integration
在这里插入图片描述

BeanFactory体系

然后查看DefaultListableBeanFactory类右键Diagrams–>show Diagrams查看结构图BeanFactory体系
4级接口体系

  • 第一级:BeanFactory 作为一个主接口不继承任何接口,暂且称为一级接口。
  • 第二级:AutowireCapableBeanFactoryHierarchicalBeanFactoryListableBeanFactory 3个子接口继承了
    它,进行功能上的增强。这3个子接口称为二级接口。
  • 第三级:ConfigurableBeanFactory 可以被称为三级接口,对二级接口 HierarchicalBeanFactory 进行了再次
    增强,它还继承了另一个外来的接口 SingletonBeanRegistry
  • 第四级:ConfigurableListableBeanFactory 是一个更强大的接口,继承了上述的所有接口,无所不包,称为
    四级接口。

为什么要多层次分割为4个接口?
接口隔离原则(ISP)原则,就是一个接口负责一个单一职责 ,采取多实现接的方式灵活组装类
查阅这些接口的源码和说明发现,每个接口都有他使用的场合,它主要是为了区分在Spring内部。 在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。

4个接口的作用:

  • BeanFactory:是Spring bean容器的根接口。最主要
    的方法就是getBean(String beanName),提供获取bean,是否包含bean,是否单例与原型,获取bean类
    型,bean 别名的api。
  • AutowireCapableBeanFactory: 提供工厂的装配功能。 |
  • HierarchicalBeanFactory :提供父容器的访问功能。及父类标注了特性,子类也能得到特性
  • ConfigurableBeanFactory 如名,提供factory的配置功能,通过XML文件加载Bean文件的能力
  • ConfigurableListableBeanFactory 集大成者,提供解析,修改bean定义,并初始化单例。
  • ListableBeanFactory 提供容器内bean实例的枚举功能.这边不会考虑父容器内的实例。

继承关系的2个抽象类和2个实现类

  • AbstractBeanFactory 作为一个抽象类,实现了三级接口 ConfigurableBeanFactory 大部分功能。
  • AbstractAutowireCapableBeanFactory 同样是抽象类,继承自 AbstractBeanFactory ,并额外实现了二级接口AutowireCapableBeanFactory 。自动注入Bean功能
  • DefaultListableBeanFactory 继承自 AbstractAutowireCapableBeanFactory ,实现了最强大的四级接口 ConfigurableListableBeanFactory ,并实现了一个外来接口BeanDefinitionRegistry ,它并
    非抽象类。(DefaultListableBeanFactory这里就是我们在初始化GenericApplicationContext时初始化的BeanFactory工厂对象,继承了4级接口实现了配置,GetBean,自动加载等方法
  • 最后是最强大的 XmlBeanFactory ,继承自 DefaultListableBeanFactory ,重写了一些功能,使自己
    更强大(Spring3.1版本后就使用DefaultListableBeanFactory 类替代了)

为什么要使用2个抽象类和2个实现类来实现
依赖倒置原则(Dependence Inversion Principle)
依赖什么?依赖于抽象类
倒置什么?将本类实现的核心代码交给抽象类,本末倒置
将一些资源加载核心资源放到抽象类当中,实现类负责加工。

Spring中有两种容器

  • BeanFactory 一个最简单的Spring容器,给依赖注入(DI)提供了基础的支持。
  • ApplicationContext 此容器添加以一些企业需要用到的东西,更加全面。它包含了BeanFactory容器
    中的东西。

到了这里我们了解清楚各个类中是做什么的就知道了在GenericApplicationContext初始化流程制造了创建了那些东西,分别是基础类加载,自动注解注入,子父级注解,配置读取类工厂构建成了BeanFactory工厂

ApplicationContext
加载注解

  ApplicationContext context =
                new AnnotationConfigApplicationContext("org.example.mvc");

理清楚DefaultListableBeanFactory类后我们回头看applicationContext类的实现,本质就是实现了4级接口的所有方法和查看父类是否有注解的工厂方法
在这里插入图片描述

ApplicationContext体系

在这里插入图片描述
ConfigurableApplicationContext

public interface ConfigurableApplicationContext extends ApplicationContext, 
Lifecycle, Closeable {
 // 配置路径的分隔符
 String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
 String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
 String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
 String ENVIRONMENT_BEAN_NAME = "environment";
 String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
 String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
 //设置此应用程序上下文的唯一ID。
 void setId(String id);
 
    //设置父容器,设置后不能再改了
 void setParent(@Nullable ApplicationContext parent);
 
    //设置environment 此处为ConfigurableEnvironment 也是可以配置的应用上下文
 void setEnvironment(ConfigurableEnvironment environment);
 
    // 此处修改父类返回值为ConfigurableEnvironment 
 @Override
 ConfigurableEnvironment getEnvironment();
 //添加一个新的BeanFactoryPostProcessor(refresh()的时候会调用的)
 void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);
 
    // 添加一个事件监听器
 void addApplicationListener(ApplicationListener<?> listener);
 
    // 注册协议处理器 允许处理额外的资源协议
 void addProtocolResolver(ProtocolResolver resolver);
 //加载或刷新配置的持久表示 最最最重要的一个方法
 //表示可以是xml、可以是注解、可以是外部资源文件等等。。。。
 // 这个方法执行完成后,所有的单例Bean都已经被实例化,Bean工厂肯定也就被创建好了
 void refresh() throws BeansException, IllegalStateException;
 
 //JVM运行时注册一个关闭挂钩,在关闭JVM时关闭此上下文,除非此时已经关闭
 void registerShutdownHook();
 
 //关闭此应用程序上下文,释放实现可能持有的所有资源和锁 包括一些销毁、释放资源操作
 @Override
 void close();
 
    //标识上下文是否激活 refresh()后就会激活
 boolean isActive();
 
    // 返回此上下文内部的Bean工厂,可以用来访问底层工厂的特定功能。通过此工厂可以设置和验证所需
的属性、自定义转换服务
 // 备注:父类方法为获得AutowireCapableBeanFactory接口,而此处的
ConfigurableListableBeanFactory可配置、可列出Bean的工厂是它的子类
 ConfigurableListableBeanFactory getBeanFactory() throws
IllegalStateException;
}

这个类在之前的方法中也提到过,主要是增强配置类,比如后置器之类的

GenericApplicationContext

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
............
}

这个类已经不是抽象类了,我们可以直接使用它。但是这个类有一个很大的缺点,因为他没有继承实现AbstractXmlApplicationContextAbstractXmlApplicationContext当中有一个,它不能读取配置的方法loadBeanDefinitions,需要我们手动去指定读取的方式及位置。但是它依旧有初始化了工厂,我们可以手动设置的注入Bean文件。因为不常用就不演示了。

AnnotationConfigApplicationContext

public class AnnotationConfigApplicationContext extends GenericApplicationContext
implements AnnotationConfigRegistry {
 private final AnnotatedBeanDefinitionReader reader;
 private final ClassPathBeanDefinitionScanner scanner;
   
   .......
}

通过 AnnotatedBeanDefinitionReader 注册配置类,用 ClassPathBeanDefinitionScanner 扫描
配置类上申明的路径,得到所有的BeanDefinition。然后其余的没啥了。这个我们经常使用,因为不用再需要xml文件了,使用 @Configuration 配置类即可,更加的方便。

文章总结

主要梳理了各个类直接的作用,是如何协同操作的,然后讲解了一下,Spring(一)里构造工厂的beanFactory是如何去构造的构造AnnotationConfigApplicationContext的时候会去构造父类的GenericApplicationContext构造函数,构造函数创建BeanFactory体系构建工厂,因为没有继承xmlapllicationcontext所以需要手动注入,因此实现了BeanDefinitionRegistry方法,构建好工厂后,创建基础扫描后置构造器。构建AnnotatedBeanDefinitionReader

   public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

第一步reader构建过程了解后,我们了解下一步,scanner的构造过程
后面我们讲解AnnotationConfigApplicationContext中Scanner扫描的构建过程


熟记各个类直接的关系和作用!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值