• Spring之IOC容器的加载过程


    1.IOC容器的加载

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

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

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

      

     

      

     <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.类图

      

     

     

      

     

     

  • 相关阅读:
    [PHP]防止表单重复提交的几种方法
    [PHP]PHP的session机制,配置与高级应用
    苹果IOS开发者账号总结--发布应用APP时team name是否可以随意写?
    转:《走出软件作坊》读书笔记
    英语学习技巧摘要
    英语学习规划与目标
    转:人生成功必读的经典语录200条
    转载: PHP错误:Warning: Cannot modify header information
    jQuery Mobile页面返回无需重新get
    mongodb type it for more
  • 原文地址:https://www.cnblogs.com/fanBlog/p/12667285.html
Copyright © 2020-2023  润新知