浅谈spring源码运行流程
源代码:主代码
第1步:
第2步:这里会循环两次,第一次refresh=false第二次为true,这里演示第二次的结果,在其中完成了容器的初始化
在refresh()函数中的方法操作如下:
1、prepareRefresh();
容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition
等
3、prepareBeanFactory(beanFactory);
配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器等
4、postProcessBeanFactory(beanFactory);
模板方法,允许在子类中对beanFactory进行后置处理。
5、invokeBeanFactoryPostProcessors(beanFactory);
实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor
的bean,在beanFactory标准初始化之后执行)。
例如:
PropertyPlaceholderConfigurer
(处理占位符)
6、registerBeanPostProcessors(beanFactory);
实例化和注册beanFactory中扩展了BeanPostProcessor
的bean。
例如:
AutowiredAnnotationBeanPostProcessor
(处理被@Autowired
注解修饰的bean并注入)
RequiredAnnotationBeanPostProcessor
(处理被@Required
注解修饰的方法)
CommonAnnotationBeanPostProcessor
(处理@PreDestroy
、@PostConstruct
、@Resource
等多个注解的作用)等。
7、initMessageSource();
初始化国际化工具类MessageSource
8、initApplicationEventMulticaster();
初始化时间广播器
9、onRefresh();
模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。
10、registerListeners();
注册监听器,广播early application events
11、finishBeanFactoryInitialization(beanFactory);
实例化所有剩余的(非懒加载)单例
比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。
实例化的过程各种BeanPostProcessor开始起作用。
12、finishRefresh();
refresh做完之后需要做的其他事情。
清除上下文资源缓存(如扫描中的ASM元数据)
初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle
接口的bean并执行start()方法)。
发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
第3步:进入方法后再221行中进行对可配置的可列表BeanFactory,obtainFreshBeanFactory的方法中的主要工作是创建DefaultListableBeanFactory实例,解析xml配置文件,最后注册bean在232行进入完成Bean工厂的初始化
第4步:实例化工厂中的单例模式,实例化对象
第5步:在这一步之前,已经完成了BeanFactory对象初始化、xml配置文件解析成BeanDefinition、BeanPostProcessor初始化与注册等操作。获取Bean对象
第6步:如图执行doGetBean方法
第7步:进行判断单例模式的判断,获取或者赋值,165行不进去的情况需要按3次。
第8步:跳这里来了
第9步:执行下一个断点
第10步:执行创建一个Bean对象的方法
第11步:
第12步:直到709行进行判断,进入709行中的instantiateBean中
第13步:在739行打上断点
第14步:接着进入实例化方法
第15步:返回一个方法
第16步:此方法中,76行进去返回就到了实体类中的构造方法
第17步:
第18步:最后返回的时候到了addSingletonFactory的方法
第19步:找出存放的对象
第20步:对象是一个concurrentHashMap的集合
第21步:执行操作后,又会进来一次,进行赋值
第22步:存放在beanName中
第23步:一路返回即可,完成读取配置文件进行对实体类的初始化
-----------------------------------------------以下开始getBean流程--------------------------------------------------
第24步:首先用主函数中进来,然后再512行中的getBeanFactory方法中跳入
第25步:进入获取Bean的工厂函数中,判断为空,返回一个私有的默认的(18行)
第26步:执行完配置Bean工厂的方法后,返回25步中,再执行getBean的方法
第27步:下一步,进入doGetBean方法中
第28步:再进入getSingletonfanfare中,进入后,在87行利用反射根据参数名获取concurrentHashMap容器中上面初始化操作中的对象,可以通过图查看提示到返回的对象HelloWorldService已经取到。