【spring源码学习】spring如何完成IOC容器构建
一、整体思路
1、整体思路
第一步:获取RootBeanDefinition
第二步:获取该BeanDefinition的依赖,将依赖关系注入到DefaultSingletonBeanRegistry中的dependentBeanMap,dependenciesForBeanMap
第三步:遍历初始化依赖关系。不进行注入,只是完成初始化(发生递归调用,重新进入第一步)
第四步:执行bean创建的前置:MethodOverride,postProcessBeforeInstantiation,postProcessMergedBeanDefinition
第五步:创建bean的对象
第六步:执行postProcessAfterInstantiation
第七步:完成依赖注入:InstantiationAwareBeanPostProcessor.postProcessProperties
第八步:执行bean的初始化方法:
(1)BeanNameAware.setBeanName(beanName)
(2)BeanClassLoaderAware.setBeanClassLoader(ClassLoader)
(3)BeanFactoryAware.setBeanFactory(beanFactory)
(4)isInitializingBean.afterPropertiesSet()
(5)自定义的初始化方法:init()
2、整理思路的算法抽象
/** * 向spring容器真正实例化1个对象的大致算法模板 * @param a * @return */ public Object createObject(String a) throws ClassNotFoundException { //step1:从缓存中获取bean Object obj=getObjectCache(a); if(obj!=null){ return obj; }else{ //step2:从BeanDefinition仓库获取bean的描述 BeanDefinition beanDefinition=getBeanDefinition(a); //step3:初始化该beanDefinition的依赖关系 String[] depends= beanDefinition.getDependsOn(); for(int i=0;i<depends.length;i++){ createObject(depends[i]); } //step4:执行创建bean对象的前置算法() //step5:创建bean的实例 obj=createInstance(Class.forName(beanDefinition.getBeanClassName())); //step6:执行创建bean的后置算法() //step7:完成bean的依赖注入 //step8:执行bean的实现spring接口的初始化方法.afterPropertiesSet,自定义的初始化方法 } return obj; } /** * 创建类对象的实例 * * @param a * @return */ public Object createInstance(Class a) { Object object = null; try { object = a.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return object; } /** * 从缓存中获取bean * @param name * @return */ public Object getObjectCache(String name){ return null; } /** * 根据beanName获取bean的描述 * @param beanBeanDefinition * @return */ public BeanDefinition getBeanDefinition(String beanBeanDefinition){ return null; } }
二、具体实现
1、spring基于xml的方式+注解方式的IOC容器组装
(1)在xml中配置注解扫描器,声明要扫描的包
<context:component-scan base-package="com.*"/>
(2)该xml配置会被spring的ContextNamespaceHandler中的解析器ComponentScanBeanDefinitionParser进行解析,按指定包进行加载类(classLoader)
第一步:基于包名生成ClassPathBeanDefinitionScanner,对包名下的类进行扫描。
第二步:扫描完后开始注入相关spring处理BeanDefinition的组件。AnnotationConfigUtils该工具类进行注入:
ConfigurationClassPostProcessor,
AutowiredAnnotationBeanPostProcessor(负责IOC的注解注入)
CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,
internalPersistenceAnnotationProcessor,
EventListenerMethodProcessor,
DefaultEventListenerFactory
(3)IOC的注入步骤
第一步:向spring获取一个bean的对象的时候,AutowiredAnnotationBeanPostProcessor会对每一个bean的创建,进行处理。去先实例化它依赖的对象。
三、关键类的功能
(1)AutowiredAnnotationBeanPostProcessor