• 【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

  • 相关阅读:
    archlinux 怎么样安装KDE界面
    选择Arch Linux还是Gentoo Linux?
    服务器用什么Linux系统较好?
    轻型简易的Linux桌面环境推荐
    扩大VMware虚拟机中linux硬盘空间
    archbang 硬盘安装
    持续改进中, Gnome Shell 2.91.3 发布
    群英战吕布 2010年十大Linux PK WIN7
    将LFSliveCD安装到硬盘的注意事项
    ArchLinux安装笔记(续)(桌面篇)
  • 原文地址:https://www.cnblogs.com/shangxiaofei/p/12287593.html
Copyright © 2020-2023  润新知