1.bean的加载在调用getbean开始,getbean调用dogetbean,dogetbean中首先转换下beanName,处理下别名和工厂名之类的,返回真正的bean名称,
2.然后先从缓存池中获取getSingleton,首先在singletonObjects缓存中查找,如果没有则从earlySingletonObjects缓存中找,如果再没有,再从singletonFactories中找,如果有则调用getObject获取实例并存放到earlySingletonObjects中,删除掉singletonFactories缓存中对应的记录,
取到实例后调用getObjectForBeanInstance判断下getBean想要的是factorybean还是bean,如果是factorybean直接返回,如果是bean则,调用factorybean的getObject
如果 不能从缓存中获取,
如果还没有,则从头开始创建,首先整合获取对应的bean定义并预先加载好dependon中依赖的相关bean
然后调用getSingleton中的另一个重载方法,传入ObjectFactory,最终调用此类的creatBean方法,
createbean中
此方法会进行override方法的检测及调用实例化前的postprocess方法,如果有产生代理对象会调用初始化后的postprocessor方法,直接返回代理对象
3.如果不是代理而且没有进行postprocessor产生结果返回的话就进入常规bean的创建,调用了doCreateBean,
3-1.首先调用createBeanInstance创建对象实例,
如果有指定工厂方法,则直接调用工厂方法返回对象,
如果没有,则按常规通过调用autowireConstructor通过beanDefinition根据参数类型定位构造函数,并判断override属性中是否有需要重写的方法,有则调用动态代理cglib创建包含拦截器方法的代理对象,没有则直接反射产生对象,
3-2.然后调用addSingleFactory将包装这getEarlyRefrence的ObjectFactory对象放进singleFactory中,暴露上一步创建好实例化好了但未初始化的对象,避免循环依赖的问题
3-3接着调用PopulateBean执行属性填充,调用autowireByName把name注入的属性抽取出来并保存到PropertyValues中,调用autowireByType把用type类型注入方式的属性设置到PropetyValues,
最后调用applyPropertyValues把获取到需要注入属性的值PropertyValues遍历设置到beanWrapper即实例化好的对象中
3-4.属性填充完后进行初始化bean,首先激活实现的Aware方法,然后调用实现的beanPostProcessor初始化前,初始化后的相关方法,最后激活自定义的init方法,包括aftrePropertiseSet及init_method
3-5.注册DisposableBean,如果有必要的话,首先如果是单例,会注册DisposableBean,如果不是则会注册DestructionCallBack方法
接下来就是获取bean的实例,getObjectForFactoryBean 根据需要最终调用的是FactoryBean的getObject来返回实例
以上主要是单例创建过程的主体部分,多例情况主要少了存放缓存的操作。直接创建并返回,因此无法解决循环依赖问题,如果多例情况下检查到循环依赖则直接抛异常
我手写一份单例主体流程图。
好吧,感觉自己也无法穷尽所有的方法步骤,毕竟Spring是一款产品级软件,加载模块作为容器初始化后的第二大块流程是核心,一张纸写完流程不可能
一次性讲完所有流程也不可能,只能挑重点讲,总的来说就是把beandefinition中的信息进行读取反射出对应的对象,其中包括了太多的细节,
三级缓存解决循环依赖,定位构造函数及参数反射生成对象,属性填充,对对象进行初始化,调用实例化前后,初始化前后的后置处理器等这一些关键特性细节我应该都有粗略点到,
并尽可能的按顺序输出。相信面试中说到这个层度应该算是童叟无欺,至少证明是我亲自点进去看过源码并且了解了个大概了吧。