Spring 容器技术

1.Spring容器技术内幕
spring容器比作一辆汽车,可以将BeanFactory看作汽车的发动机,而ApplicationContext则是一辆完整的汽车,但是它不包括发动机、离合器,等其他组件。在ApplicationContext内,各个组件按部就班,有条不紊地完成汽车的各项功能

1.1 BeanFactory和ApplicationContext简介
// Bean工厂是Spring框架最核心的接口,提供了高级Ioc的配置机制,使管理不同的java对象成为可能,所有可以被Spring容器实例化并管理的Java类都可以成为Bean(一般称BeanFactory为Ioc容器)
org.springframework.beans.factory.BeanFactory

// 应用上下文建立在BeanFactory基础之上,提供了更多面向应用的可能,易于创建实际应用。(一般称ApplicationContext为应用上下文,其实也可以成为容器)
org.springframework.context.ApplicationContext

// BeanFactory是spring框架的基础设施,面向的是spring本身
// ApplicationContext面向使用Spring框架的开发者
1.2 BeanFactory的类体系结构
1.2.1 BeanFactory的常用方法
最主要的方法就是getBean(String beanName),该方法从容器中返回特定名称的Bean,BeanFactory的功能通过其他的接口得到不断拓展

1.2.2 BeanFactory的类图结构

在这里插入图片描述

ListableBeanFactory:定义访问容器中Bean基本信息的方法
HierarchicalBeanFactory: 父子级联Ioc容器的接口
ConfigurableBeanFactory: 一个重要接口,增强了Ioc容器的可定制性。定义了设置类装载器,属性编辑器,容器初始化后置处理器等方法
SingletonBeanRegistry: 定义了允许在运行期将容器中注册单实例Bean
BeanDefinitionRegistry: 提供了向容器中手工注册BeanDefinition对象的方法(registerBeanDefinition)
1.3 ApplicationContext类体系结构
如果说BeanFactory是Spring的”心脏“,nameApplicationContext就是完整的”身躯“了。 ApplicationContext由BeanFactory派生而来

ApplicationContext的主要实现类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,接口功能如下:

ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能

MessageResource: 为应用提供il8国际化消息访问的功能

ResourcePatternResolver: 可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件
LifeCycle:该接口提供start()和stop()两种方法,用于控制异步处理过程,该接口会降start/stop的信息传递给容器中所有实现了该接口的Bean,以达到管理和控制JMX、任务调度等目的。

ConfigurableApplicationContext: 拓展于ApplicationContext,新增了两个方法refresh()和close(),让ApplicationContext具有启动、刷新和关闭应用上下文的能力。

1.4 内部工作机制
spring的AbstractApplicationContext是ApplicationContext的抽象实现类,该方法的refresh()方法定义了Spring容器在加载配置文件后的各项处理过程

在这里插入图片描述

AbstractApplicationContext#refresh()

public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
// ①初始化BeanFactory
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);

    try {
        this.postProcessBeanFactory(beanFactory);
		// ② 调用后工厂处理器
        this.invokeBeanFactoryPostProcessors(beanFactory);
		// ③ 注册Bean后处理器
        this.registerBeanPostProcessors(beanFactory);
		// ④ 初始化消息源
        this.initMessageSource();
		// ⑤ 初始化应用上下文事件广播器
        this.initApplicationEventMulticaster();
		// ⑥ 初始化其他特殊的Bean,由具体子类实现
        this.onRefresh();
		// ⑦ 注册事件监听
        this.registerListeners();
		// ⑧ 调用后工厂处理器
        this.finishBeanFactoryInitialization(beanFactory);
		// ⑨ 完成刷新并发布容器刷新事件
        this.finishRefresh();
    } catch (BeansException var9) {
        this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var9);
        this.destroyBeans();
        this.cancelRefresh(var9);
        throw var9;
    } finally {
        this.resetCommonCaches();
    }

}

}
Spring容器从加载配置文件到创建出一个完整Bean的作业流程及其参与的角色

在这里插入图片描述

1.4.1 BeanDefinition
org.springframework.beans.factory.config.BeanDefinition是配置文件元素标签在容器中的内部表示,元素标签拥有class、scope、lazy-init等配置属性,BeanDefinition则提供了相应的beanClass、scope、lazyInit类属性
BeanDefinition的类结构图如下:

在这里插入图片描述

Spring通过BeanDefinition将配置文件中的配置信息转换为容器的内部表示,并将这些BeanDefinition注册到BeanDefinitionRegister中。一般情况下,BeanDefinition只在容器启动时加载并解析,除非容器刷新或者重启。
利用容器中注册的BeanFactoryPostPorcessor对半成品的BeanDefinition进行加工处理,将以占位符表示的配置解析为最终的实际值,得到成品的BeanDefinition
1.4.2 InstantitationStrategy

在这里插入图片描述

org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy负责根据BeanDefinition对象创建一个Bean实例,接口的设计是考虑到后续可以方便的采用不同的实例化策略,以满足不同的应用需求。
SimpleInstantiationStrategy是最常用的实例化策略,仅负责实例化Bean的操作,相当于执行java语言中的new的功能,它并不会参与Bean属性的设置工作。所以由InstantiationStrategy返回回来的Bean实例实际上是一个半成品的Bean实例,属性填充的工作由BeanWrapper来完成

1.4.3 BeanWrapper(美[ˈræpər] 英[ˈræpə®])
在这里插入图片描述

org.springframework.beans.BeanWrapper相当于一个代理器,Spring委托BeanWrapper完成Bean属性的填充工作,在Bean实例被InstantiationStrategy创建出来后,通过调用BeanWrapper#setWrappedInstance方法完成属性填充。

1.5 容器事件
背景:Spring的ApplicationContext能够发布事件并且允许注册相应的事件监听器,因此它拥有一套完善的事件发布和监听机制,java通过java.util.EventObject类和java.util.EventListener接口描述事件和监听器,除了事件和监听器外,还有另外三个比较重要的概念:

事件源:事件的产生者,任何一个EventObject都必须拥有一个事件源
事件监听注册表:组件或者框架的保存地方,用来保存事件监听器。
事件广播器:事件和事件监听器沟通的桥梁,负责把事件通知给事件监听器。

在这里插入图片描述

1.5.1 Spring事件类结构
1.事件类

ApplicationEvent的唯一构造函数是ApplicationEvent(Object Source),通过source指定事件源,它有两个子类。

ApplicationContextEvent:容器事件,它拥有4个子类,表示容器启动,刷新,停止及关闭
RequestHandlerEvent:这是与Web应用相关的事件,当一个http请求被处理后,产生该事件

在这里插入图片描述

2.事件监听器接口

Spring的事件监听器都继承自ApplicationListener接口

在这里插入图片描述

可以看到ApplicationListener接口只定义了一个方法,该方法接收ApplicationEvent事件对象,其中SmartApplicationListener接口是Spring3.0新增的,它定义了两个方法,

第一个方法指定监听器支持那种类型的容器事件,它只会对该类型的事件做出反应
第二个方法指定监听器仅对何种事件源对象做出相应
其中GenericApplicationListener接口是Spring4.2新增的,该接口增强了对泛型事件类型的支持,不仅限于ApplicationEvent子类型,而是采用可解析的ResolvableType,它定义了两个方法:

第一个方法用于判断指定监听器是否支持给定的事件类型
第二个方法用于判断监听器是否支持所给定的事件源对象
3.事件广播器

在这里插入图片描述

当发生容器事件时,容器主控程序将调用事件广播器将事件通知给事件监听器注册表中的事件监听器,事件监听器分别对事件进行响应。Spring为事件广播器定义了接口,并提供了实现类

1.5.2 Spring事件体系的具体实现
// ⑤ 初始化应用上下文事件广播器
this.initApplicationEventMulticaster();
// ⑥ 初始化其他特殊的Bean,由具体子类实现
this.onRefresh();
// ⑦ 注册事件监听
this.registerListeners();
// ⑧ 调用后工厂处理器
this.finishBeanFactoryInitialization(beanFactory);
// ⑨ 完成刷新并发布容器刷新事件

Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成了体系的搭建。

在⑤处初始化事件的广播器,用户可以在配置文件中为容器定义一个自定义的事件广播器,只要实现ApplicationEventMulticaster即可,Spring会通过反射机制将其注册成容器的事件广播器。如果没找到外部事件广播器,则Spring自动使用SimpleApplicationEventMulticaster作为事件广播器。

在⑦处,Spring通过反射机制,从BeanDefinitionRegister中找出所有实现ApplicationListener的Bean,将他们注册为容器的事件监听器,实际操作就是将其添加到事件广播器所提供的事件监听器注册表中。

在⑨处,容器启动完成,调用事件发布接口向容器中所有的监听器发布事件,在publishEvent()内部可以看到,Spring委托ApplicationEventMulticaster将事件通知给事件监听器。

参考:《精通Spring4.x企业级应用开发实战》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
spring技术内幕:深入解析spring架构与计原理(第2版)》是国内唯一一本系统分析spring源代码的著作,也是spring领域的问鼎之作,由业界拥有10余年开发经验的资深java专家亲自执笔,java开发者社区和spring开发者社区联袂推荐。本书第1版不仅在内容上获得了读者的广泛好评,而且在销量上也摘取了同类书的桂冠,曾经一度掀起java类图书的销售热潮。第2版不仅继承了第1版在内容组织和写作方式上的优点,而且还根据广大读者的反馈改进了若干细节上的不足。更为重要的是,结合spring的最新版本对过时的内容进行了更新,并增加了大量新内容,使本书更趋近于完美。 《spring技术内幕:深入解析spring架构与计原理(第2版)》从源代码的角度对spring的内核和各个主要功能模块的架构、设计和实现原理进行了深入剖析。你不仅能从本书中参透spring框架的优秀架构和设计思想,还能从spring优雅的实现源码中一窥java语言的精髓。本书在开篇之前对spring的设计理念和整体架构进行了全面的介绍,能让读者从宏观上厘清spring各个功能模块之间的关系;第一部分详细分析了spring的核心:ioc容器和aop的实现,能帮助读者了解spring的运行机制;第二部分深入阐述了各种基于ioc容器和aop的java ee组件在spring中的实现原理;第三部分讲述了acegi安全框架、dm模块以及flex模块等基于spring的典型应用的设计与实现。 无论你是java程序员、spring开发者,还是平台开发人员、系统架构师,抑或是对开源软件源代码着迷的代码狂人,都能从本书中受益。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值