Spring之IOC容器的加载过程

1.IOC容器的加载

1)Resource定位(容器寻找数据的过程)

2)载入(把用户定义好的bean表示成IOC容器内部的数据结构即:BeanDefinition)

3)注册(把载入的BeanDefinition注册到IOC容器) 

 

 

 

 

1.1Bean的创建 

bean是什么时候创建的?第一次getBean的时候

 

1)检查bean是否已经存在,根据beanName获取BeanDefinition,递归获取依赖bean,根据不同属性的bean调用方法创建bean(如Singleton的,Scope的,Property的)

 doGetBean

2)检查循环引用,设置bean的属性

 createBean

3)通过不同的方式创建bean,策略模式,默认SimpleInstantiationStrategy,提供两种实例化方式,一种是BeanUtils(使用JVM的反射功能),另外一种是Cglib(字节码生成类库)

 createBeanInstance

4)属性注入如@Autowired等

 属性注入populateBean

 

1.2 实例化Bean的策略

1.Cglib

 

1.3Bean创建流程

 

 

 

 

 

 

 

 

  

 <bean id="testSpringBean" class="com.bkjk.cf.receivablesfinancing.service.TestSpringBean" init-method="init"
          destroy-method="destory">
        <property name="propertyAge" value="343434"/>
        <property name="propertyName" value="zhanfdifjidfj"/>

    </bean>
bean.xml
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);
        this.setConfigLocations(configLocations);
        if (refresh) {
            this.refresh();
        }

    }
容器启动入口
 public void refresh() throws BeansException, IllegalStateException {
         Object var1 = this.startupShutdownMonitor;
         synchronized(this.startupShutdownMonitor) {
             this.prepareRefresh();
             //这里在子类中启动refreshBeanFactory 的地方
             ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
             this.prepareBeanFactory(beanFactory);
 
             try {
                   // 设置beanFactory的后置处理
                 this.postProcessBeanFactory(beanFactory);
                  //bean注册容器
                 this.invokeBeanFactoryPostProcessors(beanFactory);
                  //注册bean的后处理,在bean创建过程中调用
                 this.registerBeanPostProcessors(beanFactory);
                  //对上下文消息进行初始化
                 this.initMessageSource();
                     //初始化上线文的事件机制
                 this.initApplicationEventMulticaster();
                  //初始化其他的特殊的bean
                 this.onRefresh();
                   //检查监听bean,并向容器注册
                 this.registerListeners();
                    //实例化所有的(non-lazy-init)单件
                 this.finishBeanFactoryInitialization(beanFactory);
                   //发布容器时间,结束Refresh过程
                 this.finishRefresh();
             } catch (BeansException var9) {
                 if (this.logger.isWarnEnabled()) {
                     this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                 }
                  //为防止容器占用资源,在异常中销毁前面已经生成的单件bean
                 this.destroyBeans();
                 //重置‘active’标签
                 this.cancelRefresh(var9);
                 throw var9;
             } finally {
                 this.resetCommonCaches();
             }
 
         }
     }
refresh()方法
//创建 BeanFactory 并载入BeanDefinition
 protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }

        return beanFactory;
    }
 protected final void refreshBeanFactory() throws BeansException {
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
             //创建beanFactory
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
            //载入bean入口
             this.loadBeanDefinitions(beanFactory);
            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }
载入BeanDefinition入口
 //AbstractXmlApplicationContext 
// XmlBeanDefinitionReader 定位resource,XmlBeanDefinitionReader 
  protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        this.initBeanDefinitionReader(beanDefinitionReader);
        this.loadBeanDefinitions(beanDefinitionReader);
    }
定位resource
//IOC 容器加载的核心方法
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
                 try {
                InputStream inputStream = encodedResource.getResource().getInputStream();
                try {
                    //一:读取xml文件
                    InputSource inputSource = new InputSource(inputStream);
                    if (encodedResource.getEncoding() != null) {
                        inputSource.setEncoding(encodedResource.getEncoding());
                    }
                     //二:加载 beanefinition
                    var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                } finally {
                    inputStream.close();
                }
            } 

            return var5;
        }
    }


protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
        try {
             //一 1) 将xml文件转换为document
            Document doc = this.doLoadDocument(inputSource, resource);
            return this.registerBeanDefinitions(doc, resource);
}
}

           //一 2) 开始执行
  public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        this.logger.debug("Loading bean definitions");
        Element root = doc.getDocumentElement();
        this.doRegisterBeanDefinitions(root);
    }

 protected void doRegisterBeanDefinitions(Element root) {
       
        this.preProcessXml(root);
      //三 解析Element 获取xml内容
        this.parseBeanDefinitions(root, this.delegate);
        this.postProcessXml(root);
        this.delegate = parent;
    }
    //解析Element 得到node 判断node内容
 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes(); 
            for(int i = 0; i < nl.getLength(); ++i) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element)node;
                    if (delegate.isDefaultNamespace(ele)) {
                      //读取document的内容
                        this.parseDefaultElement(ele, delegate);
                    } else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        } else {
            delegate.parseCustomElement(root);
        }

    }

      //四 判断xml中(document中节点的类型)
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, "import")) {
            this.importBeanDefinitionResource(ele);
        } else if (delegate.nodeNameEquals(ele, "alias")) {
            this.processAliasRegistration(ele);
        } else if (delegate.nodeNameEquals(ele, "bean")) {
             /* 五 载入beanDefinition  这里只是读取<bean>中的设置的class的name, 然后载入到BeanDefinition中,只是做个记录,并不设计对象的实例化,对象的实例化是在依赖注入时完成的*/
            this.processBeanDefinition(ele, delegate);
        } else if (delegate.nodeNameEquals(ele, "beans")) {
            this.doRegisterBeanDefinitions(ele);
        }

    }
          //五 载入BeanDefinition 这里得到documentReader后,为具体的spring bean 解析准备了数据 
protected void processBeanDefinition(Element ele, eanDefinitionParserDelegate delegate) {
              //具体处理了BeanDefinition交给 BeanDefinitionParserDelegate
           /* 具体将<bean>的内容进行解析,解析为spring 的BeanDefinition
           BeanDefinitionHolder是BeanDefinition对象的封装,封装了bean的名称和别 
      名,用他来完成   向IOC容器注册,得到的BeanDefinitionHolder是通过beanDefinitionParserDelegate 对 XML的元素的信息按照spring 的bean规则进行解析得到的*/
  BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); 
       if (bdHolder != null) {  
          bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);  
        try {  
             BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());  
             } catch (BeanDefinitionStoreException var5) {  
             this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);  
             }  
            // BeanDefinition向IOC容器注册之后,发送消息
            this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));   
              }  
             } 


//载入BeanDefinition 
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
        String id = ele.getAttribute("id");
        String nameAttr = ele.getAttribute("name");
        List<String> aliases = new ArrayList();
        if (StringUtils.hasLength(nameAttr)) {
            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
            aliases.addAll(Arrays.asList(nameArr));
        }

        String beanName = id;
        if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
            beanName = (String)aliases.remove(0);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
            }
        }

        if (containingBean == null) {
            this.checkNameUniqueness(beanName, aliases, ele);
        }
       //将xml的内置转换为spring的bean信息
        AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
       }


    //对<bean>的内容进行解析,转换为spring的bean
    public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {
        this.parseState.push(new BeanEntry(beanName));
        String className = null;
        if (ele.hasAttribute("class")) {
            className = ele.getAttribute("class").trim();
        }

        String parent = null;
        if (ele.hasAttribute("parent")) {
            parent = ele.getAttribute("parent");
        }

        try {
             //生成需要的BeanDefinition对象,为BeanDefinition的载入做准备
            AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
             //设置<bean>的attribute scope,init,destory 等
            this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
            //设置元数据 如 key ,value这样的
            this.parseMetaElements(ele, bd);
            this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
              //解析<bean>构造函数 
            this.parseConstructorArgElements(ele, bd);
             //设置<bean>property元素
            this.parsePropertyElements(ele, bd);
            this.parseQualifierElements(ele, bd);
            bd.setResource(this.readerContext.getResource());
            bd.setSource(this.extractSource(ele));
            AbstractBeanDefinition var7 = bd;
            return var7;
        } 
        } finally {
            this.parseState.pop();
        }

        return null;
    }
 
载入BeanDefinition的核心实现
/注册 BeanDefinition
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        //获取bean的 名称
     String beanName = definitionHolder.getBeanName();
       //注册bean 并将bean放入到ioc容器里面 
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            String[] var4 = aliases;
            int var5 = aliases.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String alias = var4[var6];
                //注册其他信息 是否是单例,是否允许重载 是否是abstract 类
                registry.registerAlias(beanName, alias);
            }
        }

    }

//DefaultListableBeanFactory 具体执行注册的
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition)beanDefinition).validate();
            } catch (BeanDefinitionValidationException var9) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
            }
        }
              //bean 已经存在
        BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
           //不允许覆盖 报异常
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + existingDefinition + "] bound.");
            }     
            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
            if (this.hasBeanCreationStarted()) {
                Map var4 = this.beanDefinitionMap;
                     //synchronized,保证数据一致性
                synchronized(this.beanDefinitionMap) {
                   //将bean放入容器
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    if (this.manualSingletonNames.contains(beanName)) {
                        Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            } else {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }
        
        if (existingDefinition != null || this.containsSingleton(beanName)) {
            this.resetBeanDefinition(beanName);
        }

    }
向IOC容器注册

 

2.BeanDefinition是什么?

是一个接口,里面定义了一些bean的元数据,如beanName,score等,是对xml中<bean>的抽象

 

3.类图

 

  

 

 

  

 

 

 4.面试题

BeanFactoryPostProcessor

修改BeanDefinition信息,修改bean的元信息,此时Bean还未初始化

  

  自定义BeanFactoryPostProcessor

MyBeanFactoryPostProcessor

 

BeanPostProcessor

是在Bean创建完成,属性填充完之后执行的

 

  

initializeBean中调用BeanPostProcessor

自定义BeanPostProcessor

MyBeanPostProcessor

 

posted @ 2020-04-09 16:56  暖暖-木木  阅读(2432)  评论(0编辑  收藏  举报