zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    linux的vim按了ctrl+s之后假死的解决办法
    linux下的终端模拟器urxvt的配置
    vim下正则表达式的非贪婪匹配
    linux中的一个看图的软件
    解决windows的控制台显示utf8乱码的问题
    [PHP][位转换积累]之异或运算的简单加密应用
    [PHP][REDIS]phpredis 'RedisException' with message 'read error on connection'
    [PHP][位转换积累]之与运算截取二进制流的值
    [PHP][位转换积累]之pack和unpack
    [正则表达式]PCRE反向分组引用
  • 原文地址:https://www.cnblogs.com/shangxiaofei/p/12287593.html
Copyright © 2011-2022 走看看