spring源码(一)主流程

之前看spring源码,看一部分就写了一部分的笔记,并没有把很多流程总结出来,所以今天我就把之前看的spring加载的主流程梳理了下,方便之后在主流程的基础上各个分支功能的拓展。

spring应该从什么地方开始看起

1.可以根据你要了解的功能入手,debug一步步走下去
2.可以根据bean创建的主流程看起,个人比较推荐,(先熟悉了主流程,之后按功能入手会比较轻松)

spring的主流程

创建上下文容器

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(“spring.xml”);

设置需要加载的本地配置

setConfigLocations(configLocations);

refresh流程

refresh()

准备上下文的刷新,设定容器启动时间,设定活跃标志位为true,执行初始化属性资源(未实现,自定义容器可以实现),属性验证

prepareRefresh()

刷新内部的bean工厂,从configLocations配置文件中加载beandefinition到beanfactory,通过dom解析元素,并判断是否是自定义的标签,如果是就调用自定义的解析器,根据标签名获取对应的命名空间处理器,并调用它自己注册的解析器解析获得beandefinition

obtainFreshBeanFactory()

配置工厂的标准上下文特征,类加载器、后置处理器等

prepareBeanFactory(beanFactory);

标准初始化之后还可以修改内部bean工厂,比如:在beandefinition被加载,但bean没有实例化前,允许我们自定义的容器中注册自定义的beanpostprocess

postProcessBeanFactory(beanFactory);

调用beanfactorypostprocess和beandefinitionregistrypostprocess的postprocess*()方法,例如:PropertyPlaceholderConfigurer的processProperties方法我们可以在子类实现一个工具类加载properties文件

invokeBeanFactoryPostProcessors(beanFactory);

注册拦截bean创建的beanpostprocess,并加入到bean工厂中,(按实现的接口排序注册)

registerBeanPostProcessors(beanFactory);

初始化消息资源

initMessageSource();

初始化组播器,没有就创建

initApplicationEventMulticaster();

模板方法,待子类实现的自定义刷新

onRefresh();

注册监听器放入组播器中,监听器会对特定的事件处理,每调用一个监听器就会在线程池中支持新的线程

registerListeners();

实例化所有非懒加载的单例bean

finishBeanFactoryInitialization(beanFactory);

初始化生命周期处理器,并调用他的刷新方法,发布容器已刷新事件

finishRefresh();

重置Spring核心中的常见自省缓存,因为我们可能不再需要用于单例bean的元数据…

resetCommonCaches();

spring创建bean的生命周期

实例化所有非懒加载的单例bean

finishBeanFactoryInitialization(beanFactory);

------------------------------------------->
实例化所有的单例

beanFactory.preInstantiateSingletons();

获取bean实例,获取工厂bean时需要加&前缀

getBean(beanName);
doGetBean(name, null, null, false);

创建bean实例

createBean(beanName, mbd, args);

创建代理类?根据被代理的目标类是否实现了接口,是否优化来判断使用哪种代理(jdk获取cglib)

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

创建bean

doCreateBean(beanName, mbdToUse, args);

创建bean实例,可以是工厂方法创建,也可以是自动构造器反射构建

createBeanInstance(beanName, mbd, args);

属性赋值

populateBean(beanName, mbd, instanceWrapper);

初始化bean

initializeBean(beanName, exposedObject, mbd);

调用实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware的set方法

invokeAwareMethods(beanName, bean);

调用beanpostprocess的postProcessBeforeInitialization方法

applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

调用客户端自己的初始化方法,如果实现了InitializingBean接口会先调用afterPropertiesSet();

invokeInitMethods(beanName, wrappedBean, mbd);

用beanpostprocess的postProcessBeforeInitialization方法postProcessAfterInitialization(result, beanName);

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

spring加载配置文件构建beandefinition

beandefinition加载流程

obtainFreshBeanFactory();

--------------------------------------->
刷新beanfactory,没有创建需要创建beanfactory

refreshBeanFactory();

加载beandefinition

loadBeanDefinitions(beanFactory);

根据beandefinitionreader加载beandefinition

loadBeanDefinitions(beanDefinitionReader);

从配置文件中加载beandefinition

reader.loadBeanDefinitions(configLocations);

加载resource资源

loadBeanDefinitions(location, null);

把资源编译下

loadBeanDefinitions(resource);

把资源转换成流的形式

loadBeanDefinitions(new EncodedResource(resource));

根据流和资源,dom解析成document对象

doLoadBeanDefinitions(inputSource, encodedResource.getResource());

documentReader注册beandefinition

registerBeanDefinitions(doc, resource);

根据dom对象获取根元素Element

documentReader.registerBeanDefinitions(doc, createReaderContext(resource));

解析元素

doRegisterBeanDefinitions(root);

解析各种类型的元素标签,分为默认标签和用户自定义标签

parseBeanDefinitions(root, this.delegate);

解析用户自定义标签(除了bean、alias、import)

delegate.parseCustomElement(root);

根据元素获取对应的NamespaceHandler命名空间处理器,并解析。

handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值