spring源码深度解析-2功能扩展

容器功能的扩展
ApplicationContext用于扩展BeanFactory中现有的功能。究竟多出了哪些功能,进一步探索。写法上:
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));

ApplicationContext bf = new ClassPahtApplicationContext("beanFactoryTest.xml");
还是以ClassPahtApplicationContext作为切入点:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}

ClassPahtApplicationContext可以对数据进行解析并进行加载,而对于解析及功能实现都是在refresh()中实现

setConfigLocations(String... locations):设置配置路径
用于解析给定的路径数组,如果数组中包含特殊符号如$(var),那么resolvePath中会搜索匹配的变量并替换

refresh();扩展功能
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
initMessageSource();

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
onRefresh();

// Check for listener beans and register them.
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
finishRefresh();
}
}
}
1_ prepareRefresh()初始化的准备工作,例如对系统属性或者环境变量进行准备及验证。
2_ obtainFreshBeanFactory 初始化BeanFactory,并进行XML文件读取
ClassPathXmlApplicationContext包含着BeanFactory所提供的一切特征,在这一步中将会复用BeanFactory中的配置文件读取解析及其它功能,这一步之后,ClassPathXmlApplicationContext实际上就包含了BeanFactory所提供的功能,也就是可以进行Bean的提取等基础操作了
3_ prepareBeanFactory() 对BeanFactory进行各种功能填充
@Qualifier与@Autowired正式在这一步骤中提供的支持
4_ postProcessBeanFactory() 子类覆盖方法做额外处理
postProcessBeanFactory是一个空函数,需要自己重写子类,覆盖方法来方便在业务上进行扩展
5_ invokeBeanFactoryPostProcessors(beanFactory) 激活各种BeanFactory处理器
6_ registerBeanPostProcessors(beanFactory) 注册拦截bean创建的bean处理器,这里只是注册,真正的调用在getBean的时候。
7_ initMessageSource() 为上下文初始化Message源,即对不同语言的消息体进行国际化处理。
8_ initApplicationEventMulticaster() 初始化应用消息广播器,并犯法如“applicationEventMuliticaster”bean中。
9_ onRefresh()留个子类初始化其他的bean
10_ registerListeners() 在所有注册的bean中查找listener bean,注册到消息广播器中
11_ finishBeanFactoryInitialization(beanFactory) 初始化剩下的单实例(非惰性的)。
12_ finishRefresh()完成刷新功能,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人。

1__ prepareRefrsh 主要做些准备工作,例如对系统属性和环境变量的初始化及验证
里边两个主要的方法initPropertySources(),validateRequiredProperties()。
initPropertySources,用户根据自己的需要重写initPropertySources()方法,并在方法进行个性化的属性处理及设置
validateRequiredProperties,对属性验证。如:工程需要某个设置(VAR)从系统环境变量中获取,如果用户没配这个变量,那么系统不能工作。这一要求在spring就可以自定义一个类集成ClassPathXmlApplicationContext,在initPropertySources()里用getEnviroment().setRequiredProperties("VAR")设置这个属性,那么在验证的就是验证这个属性,没有就会报错。当然也要在使用的时候替换掉原有的ClassPathXmlApplicationContext:ApplicationContext bf = new MyApplicationPathApplicationContext("test.xml");
2__ obtainFreshBeanFactory
加载BeanFactory,经过这个函数后,ApplicationContext就有了BeanFactory的全部功能。这个方法里的步骤:
1.创建DefaultListableBeanFactory
前面用的BeanFactory bf = new XmlBeanFactory("text.xml")中的XmlBeanFactory继承自DefaultListenBeanFactory,并提供了XmlBeanDefinitionReader属性,也就是说DefaultListenBeanFactory是容器的基础。必须首先实例化。
2.是定序列化ID
3.定制BeanFactory
customizeBeanFactory(beanFactory)
4.加载BeanDefinition
5.使用全局变量记录BeanFactory类实例。因为DefaultListenBeanFactory类型的变量beanFacotory是函数内的局部变量,所有要用全局变量来记录解析结果。
3_ customizeBeanFactory(beanFactory)
这里已经开始了对BeanFactory的扩展,在基本容器的基础上,增加了是否允许覆盖是否允许扩展的设置并提供了@Qualifier和@Autowired的支持。允许覆盖允许扩展只是判断了是否为空,为空就进行设置,但是在此之前哪个地方来设置它并没有看见,还是在子类的customizeBeanFactory覆盖方法中进行设置。接下来就是加载BeanDefinition,需要XmlBeanDefinitionReader来读取xml,这里首先初始化它,调用loadBeanDefinitions方法,和前面说的Beanfactory的加载一模一样。
这里还有很多细节。(书的135页)
3__ prepareBeanFactory() 功能扩展
1增加SPEL语言的支持
2增加属性注册编辑器
spring在DI的时候类似于Date这种属性无法识别,会报错,可以有两种方法解决
1:使用自定义属性编辑器
2:注册spring自带的属性编辑器CustomDateEditor
3添加ApplicationContextAwareProcessor处理器
对于beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))的主要目的就是注册个BeanPostProcessor。真正的逻辑还在ApplicationContextAwareProcessor中。ApplicationContextAwareProcessor实现BeanPostProcessor接口。之前在bean实例化的时候,也就是spring激活bean的init-method的前后,会调用BeanPostProcessor的postProcessBeforeInitialization方法和postProcessAfterInitialization方法,同样对于ApplicationContextAwareProcessor我们也看这两个方法。
postProcessAfterInitialization方法没有做过多逻辑处理
postProcessBeforeInitialization方法,其中主要的逻辑是调用了invokeAwareInterfaces,从这个方法代码中能看出主要是实现这些Aware接口在被初始化的后,可以获得一些对应的资源。
4.设置忽略依赖。将ApplicationContextAwareProcessor注册后,invokeAwareInterfaces方法中间接调用的Aware已经不是普通的bean了,需要在spring做bean的依赖注入的时候忽略他们。
5.注册依赖。当注册了依赖解析后,例如当注册了对BeanFactory.Class的解析依赖后,当bean的属性注入的时候,一旦检测属性为BeanFactory类型便会将实例beanFactory注入进去。
4_ postProcessBeanFactory BeanFactory的后处理
11_ finishBeanFactoryInitialization(beanFactory)
完成BeanFactory的初始化工作,其中包括ConversionService的设置、配置冻结以及非延迟加载的bean的初始化工作。
1.ConversionService的设置。之前说过用自定义类型转化器可以从String转Date,spring中还提供了另外一种转换方式:使用Converter。
2.冻结配置。冻结所有的bean定义说明注册的bean定义将不能被修改或进行任何进一步处理。
3.初始化非延迟加载。ApplicationContext实现的默认方式就是在启动的时候将所有的单例bean提前实例化,通常只是好事,因为这样在配置的中的错误能马上就发现。这个实例化的过程是在finishBeanFactoryInitialization中完成的。
12_ finishRefresh
在spring中还提供了Lifecycle接口,包好start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始生命周期,并在关闭的时候调用stop方法接受生命周期,通常用来配置后台程序,在启动后一直运行(如对MQ进行轮询)。
1.initLifecycleProcessor:当ApplicationContext启动或停止时,会通过LifecycleProcessor来与所有的bean的周期做状态更新,而在使用前需要初始化
2.onRefresh:启动所有实现了Lifecycle接口的bean
3.publishEvent:当完成ApplicationContext初始化的时候,要通过Spring中的时间发布机制来发出ContextRefreshEvent事件,保证对应的监听器可以进一步的逻辑处理。

时间: 2024-10-10 08:42:05

spring源码深度解析-2功能扩展的相关文章

Spring源码深度解析pdf

下载地址:网盘下载 <Spring源码深度解析>从核心实现和企业应用两个方面,由浅入深.由易到难地对Spring源码展开了系统的讲解,包括Spring的设计理念和整体架构.容器的基本实现.默认标签的解析.自定义标签的解析.bean的加载.容器的功能扩展.AOP.数据库连接JDBC.整合MyBatis.事务.SpringMVC.远程服务.Spring消息服务等内容. <Spring源码深度解析>不仅介绍了使用Spring框架开发项目必须掌握的核心概念,还指导读者如何使用Spring框

Spring源码深度解析第一天

其实第一天已经过去了,今天是第二天.iteye刚注册的小号就被封了.不论是它的失误还是他的失误总之我跟iteye是没有缘分了. 昨天基本没有进展.所以从今天开始说了.下面流水账开始了. <Spring源码深度解析>这本书没有pdf完整版是让我很失望的.如果有完整版即使看完了我也会选择买一本实体如果有用的话. 书中说从github下载源码.发现github没有想象中的简单易懂.还需要记忆很多命令才能玩得转.从github上获得了Spring源码后需要使用Gradle来编译成eclipse项目.g

spring源码深度解析— IOC 之 开启 bean 的加载

概述 前面我们已经分析了spring对于xml配置文件的解析,将分析的信息组装成 BeanDefinition,并将其保存注册到相应的 BeanDefinitionRegistry 中.至此,Spring IOC 的初始化工作完成.接下来我们将对bean的加载进行探索. 之前系列文章: spring源码深度解析— IOC 之 容器的基本实现 spring源码深度解析— IOC 之 默认标签解析(上) spring源码深度解析— IOC 之 默认标签解析(下) spring源码深度解析— IOC

SPRING技术内幕,Spring源码深度解析

 SPRING技术内幕,Spring源码深度解析 SPRING技术内幕:深入解析SPRING架构与设计原理(第2版)[带书签].pdf: http://www.t00y.com/file/78131650 Spring源码深度解析 [郝佳编著] sample.pdf: http://www.t00y.com/file/78131634 [jingshuishenliu.400gb.com]Spring Data.pdf: http://www.t00y.com/file/78256084 [

1.2 Spring环境搭建--Spring源码深度解析

前言: Spring 的源码已经从 svn 迁移到 GitHub.而且也改为基于 Gradle 的构建来构建项目.它取代了之前的 Ant+Ivy 系统,所以要构建 Spring 源码环境首先要安装 GitHub 以及 Gradle. 安装 GitHub Windows 系统对应的 GitHub 版本下载地址为: http://windows.github.com/.如图所示:

书籍摘要-spring 源码深度解析

第 1 章:spring 整体架构和环境搭建 spring 是分层的,主要分为网络层.数据库连接层.核心容器层. AOP 层和测试层. 核心容器中实现了 IOC 和依赖注入,方法是 BeanFactory.数据库连接层封装了 JDBC,兼容多种 ORM 框架. 第 2 章:容器的基本实现 DefaultListableBeanFactory 是加载 Bean 的核心类,XmlBeanFactory 继承了这个类. 分三步走,首先获取 XML 文件验证模式原理,然后将文件转换成 Document

Spring源码深度解析,事务案例讲解高级

Spring的整体架构Spring框架是一个分层架构,它包含一系列的功能要素,并被分为大约20个模块,如下图所示 这些模块被总结为以下几个部分: Core Container Core Container(核心容器)包含有Core.Beans.Context和Expression Language模块 Core和Beans模块是框架的基础部分,提供IoC(转控制)和依赖注入特性.这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许

Spring源码深度解析-《源码构建》

1.导入spring-framework-3.2.x\spring-beans之前先导入源码spring-framework-3.2.x\spring-core,否则报错: 2.导入spring-asm-repack-5.0.4.jar和spring-cglib-repack-3.1.jar https://blog.csdn.net/baidu_19473529/article/details/79518685 https://blog.csdn.net/ywb201314/article/d

1.1 Spring的整体架构--Spring源码深度解析

前言: Spring 始于2003年,轻量级 Java 开源框架. Spring 是为了解决企业应用开发的复杂性而创建的,它使用基本的 JavaBean 来完成以前只可能由 EJB 完成的事情. Spring 的用途不仅限于服务器端的开发,从简单性.可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益. Spring 的整体架构: Spring 框架是一个分层架构,被分为大约20个模块. (1)Core Container Core Container (核心容器)包含