spring框架类和接口数目众多,各种方法调用关系复杂,细节也很多,在此把自己对于从容器初始化到bean装配到容器spring实现ioc,aop及一些需要注意的地方记录一下。需要注意的是AbstractApplicationContext AbStractBeanFactroty 这两个抽象类采用了许多模板方法模式,工厂模式,观察者模式。
1.org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
applicationContext有许多实现类以ClassPathXmlApplicationContext构造函数为例。
2.org.springframework.context.support.AbstractApplicationContext#refresh
3.org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
4.org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons 这里例举容器的所有beandifinition的名称调用第5步。
5.org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
6.org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
7.org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
8.org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
第8步骤查1级缓存sigletonobjects是否存在,如果不存在查二级缓存earlrysigletonobjects和三级缓存sigletonfactory; 三个缓存都不存在进入第9步。否则返回bean。
9.org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory>)
该方法第2个参数外面传的lamd表达式接口对象,到里面才调用的注意方法写在外面。
10.org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation这个方法设置当前bean处于创建中的状态。只要是单例模式的bean, singletonsCurrentlyInCreation标志都为true代表需要提前曝光加入三级缓存。
11.org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String,org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
这步调用是lambda表达式传入第9步里的。
12.org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
13.org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance实例化bean,调用构造函数。
下面判断是否singletonsCurrentlyInCreation是否为true,从前面来看这里单例模式都为true,为解决循环依赖进入14 - 15步骤步后面
14.org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory 加入单例工厂(三级缓存)
15.org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference 这步调用实现SmartInstantiationAwareBeanPostProcessor接口的org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference实现aop代理proxy的对象提前曝光。这里代理对象提前曝光持有目标对象引用,代理对象提前曝光当作属性注入其他对象,而其他对象先初始化成功后又作为属性注入目标对象,从而解决循环依赖。
16 .org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 这里注入属性和依赖,里面会根据name和type 递归调用第5步方法,循环依赖在这里发生。如果有循环依赖取的是14步保存的对象,解决循环依赖也就是解决了递归死循环的问题。
17.org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
这步进行初始化bean分别进行beanpostprocessor的前置方法,afterpropertist方法,自定义initmethod, beanpostprocessor后置的方法的调用,需要注意由于AOP相关BeanPostProcessor在前面已经提前曝光生成了,这里的方法会判断不会再进行代理的生成。
到这步bean已经生成好了。
18.org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean) 这里需要再次调用该方法从二级缓存返回生成的aop代理对象。以便后面执行19步放入一级缓存。
19. org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory>)方法中下面的
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton 加入一级缓存SingletonObjects,同时移除二级和三级缓存。至此bean已经完成装配初始化放入容器中。