这是一种基于xml的spring上下文对象,这里介绍下它的启动流程
org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)
这个是常用的构造方法,传入参数为配置文件路径(见#1),其中内部实现为设置this对象的parent对象及传入参数的路径转换器,然后进入spring的核心方法——refresh,这个方法是由spring的抽象上下文类提供的,具体位置org.springframework.context.support.AbstractApplicationContext#refresh,这个核心方法包括prepareRefresh,obtainFreshBeanFactory,prepareBeanFactory,postProcessBeanFactory,invokeBeanFactoryPostProcessors,registerBeanPostProcessors,initMessageSource,initApplicationEventMulticaster,onRefresh,registerListeners,finishBeanFactoryInitialization,finishRefresh等一系列方法。
#1
#2
#3
prepareRefresh
这里主要做了检查必要属性和注册监听等事情
obtainFreshBeanFactory
获取一个BeanFactory对象,如果当前存在该对象,则摧毁bean,并关闭BeanFactory对象,最终获取一个DefaultListableBeanFactory对象,然后做了属性的设置,主要是是否允许bean被重写和是否允许循环依赖(#4)然后执行loadBeanDefinitions方法(#5这个方法属于AbstractXmlApplicationContext),里面构建了一个xml解析对象XmlBeanDefinitionReader,调用它的loadBeanDefinitions方法,采用模板设计模式,调用到子类的getConfigResources方法,获取配置资源地址(#6),交由XmlBeanDefinitionReader进行解析,一路断点,走到真实解析的方法(#7),最重要的方法doRegisterBeanDefinitions,是真实解析xml的方法,会根据当前的xml标签是否为默认的标签,如果为false,则会获取其名称空间,根据名称空间获得一个NamespaceHandler对象,由该对象进行bean的注册,其中readerContext作为获取名称空间和NamespaceHandler映射转换的类(#8)。
**
#4
#5
#6
#7
8

prepareBeanFactory
在这个方法中,注册了一些默认的bean,以及一些BeanPostProcessor等,具体主要有ApplicationContextAwareProcessor,和一些特殊依赖转换,如BeanFactory等
postProcessBeanFactory
这个类在本上下文中没有具体的实现
invokeBeanFactoryPostProcessors
这个方法其实就是处理埋点(#9),具体的实现中会获取所有上下文中的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor对象,然后根据PriorityOrdered,Ordered进行排序执行
9

registerBeanPostProcessors
与invokeBeanFactoryPostProcessors类似,但这里主要处理的是BeanPostProcessor对象,这个对象主要处理bean实例化的前操作和后操作,唯一和上面方法的区别是,这里仅仅是添加到BeanFactory的beanPostProcessor集合中,等待后续调用
initMessageSource
往spring上下文中注册了一个messageSource的bean,用于国际化
initApplicationEventMulticaster
往spring上下文中注册了一个应用事件广播的bean
onRefresh
空的实现,作为钩子方法的存在,如嵌入式tomcat的启动等
registerListeners
注册监听的bean,作为广播bean的回调
finishBeanFactoryInitialization(最重要)
往beanFactory对象里加入了字符串转换器,主要用于转换xml中从properties中读取内容(#10),最后开始初始化bean的调用(#11)。首先会获取所有的bean的id,判断是否为FactoryBean的子类,如果是,则在bean的id前加入“&”。然后一路往下,一直到doGetBean方法,先从singletonObjects中查看是否存在,如果不存在,查看是否在创建中的列表中,根据bean的作用域,如果是单例,会走到AbstractBeanFactory的createBean方法,首先会给注册的beanPostProcessor一次执行并返回实例的机会,一般用不到(#13),最后走到doCreateBean方法,这里会判断,如果是单例,并且在FactoryBean创建的缓存中存在,如果存在直接返回(#14),否则继续往下执行采用反射进行对象实例化,在#15中,会寻找适配的构造器、factory-method,instanceSupplier来构建,如果没有带参且需要依赖注入的构造器,那么默认用无参构造函数,构造完成后,注入依赖(#16),获取PropertyValues对象,里面包含了bean的所有属性,如果有需要注入的对象,则执行属性对象的getBean操作(#17),判断是否运行时属性(#18),在这里真正触发beanFactory的getBean方法(#19),最终在getSingleton解决循环依赖(#20),当为单例且允许循环依赖的条件下,会放入3级缓存(#21),当ServiceB在3级缓存找到ServiceA时,将ServiceA从3级缓存移除,加入2级缓存(#22)。当bean实例化完成后,会执行接口实现方法,如实现了BeanFactoryAware的setBeanFactory方法等,然后执行前面在registerBeanPostProcessors方法中注册到上下文的BeanPostProcessor的before方法,接着执行实现了InitializingBean接口的afterPropertiesSet方法,最后执行BeanPostProcessor的after方法,这个方法尤为重要,因为在这里将完成切面的寻找,动态代理,spring的声明式事务就是在这里作为增强点生成代理对象。整个对象完成实例化并注入依赖后,加入1级缓存(#23)
10

11

12

13

#14

15

16

17

18

#19

#20

21

22

23

finishRefresh
清除resourceCaches缓存
初始化生命周期处理器
发布ContextRefreshedEvent事件
最后再来个冷知识点,请看#24,在那里可以搞破坏,实现接口,然后返回false,那么依赖将无法注入
**
#24
