【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;
    }
}
View Code

二、具体实现

1、spring基于xml的方式+注解方式的IOC容器组装

(1)在xml中配置注解扫描器,声明要扫描的包

<context:component-scan base-package="com.*"/>
View Code

(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

原文地址:https://www.cnblogs.com/shangxiaofei/p/12287593.html