zoukankan      html  css  js  c++  java
  • Spring IOC registerBeanDefinition

           IOC 是Spring的核心,我们以编程方式使用DefaultListableBeanFactory,尽管在现实的编码过程中几乎不会这种原始的方式,但是作为了解Spring IOC 实现还是很有必要的。

      

    //创建IOC配置的抽象资源
    		ClassPathResource resource=new ClassPathResource("client.xml");
    		//创建一个BeanFactory
    		DefaultListableBeanFactory beanFactory=new DefaultListableBeanFactory();
    		//创建一个BeanDefinition读区器
    		XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(beanFactory);
    		//从定义好的资源位置读区配置信息
    		reader.loadBeanDefinitions(resource);
    

    通过上述步骤我们就创建好了一个beanFactory.在XmlBeanDefinitionReader中实际加载BeanDefinition的方法是doLoadBeanDefinitions,在该方法中首先是将资源文件转换为Document对象,然后注册BeanDefinition

       

    /**
    	 * Actually load bean definitions from the specified XML file.
    	 * @param inputSource the SAX InputSource to read from
    	 * @param resource the resource descriptor for the XML file
    	 * @return the number of bean definitions found
    	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
    	 * @see #doLoadDocument
    	 * @see #registerBeanDefinitions
    	 */
    	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    			throws BeanDefinitionStoreException {
    		try {
    			Document doc = doLoadDocument(inputSource, resource);
    			return registerBeanDefinitions(doc, resource);
    		}
    		catch (BeanDefinitionStoreException ex) {
    			throw ex;
    		}
    /**
    	 * Register the bean definitions contained in the given DOM document.
    	 * Called by {@code loadBeanDefinitions}.
    	 * <p>Creates a new instance of the parser class and invokes
    	 * {@code registerBeanDefinitions} on it.
    	 * @param doc the DOM document
    	 * @param resource the resource descriptor (for context information)
    	 * @return the number of bean definitions found
    	 * @throws BeanDefinitionStoreException in case of parsing errors
    	 * @see #loadBeanDefinitions
    	 * @see #setDocumentReaderClass
    	 * @see BeanDefinitionDocumentReader#registerBeanDefinitions
    	 */
    	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    		//创建一个BeanDefinitionDocumentReader 实例
    		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    		//获取当前BeanFactory中的beans数量
    		int countBefore = getRegistry().getBeanDefinitionCount();
    		//注册beanDefinition
    		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    		//返回本次注册bean的数量
    		return getRegistry().getBeanDefinitionCount() - countBefore;
    	}

      在DefaultBeanDefinitionDocumentReader中注册bean的代码如下:

    /**
    	 * Register each bean definition within the given root {@code <beans/>} element.
    	 */
    	protected void doRegisterBeanDefinitions(Element root) {
    		
    		BeanDefinitionParserDelegate parent = this.delegate;
    		this.delegate = createDelegate(getReaderContext(), root, parent);
    
    		if (this.delegate.isDefaultNamespace(root)) {
    			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
    			if (StringUtils.hasText(profileSpec)) {
    				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
    						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
    				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
    					return;
    				}
    			}
    		}
    		//前置处理
    		preProcessXml(root);
    		//解析BeanDefinition
    		parseBeanDefinitions(root, this.delegate);
    		//后置处理
    		postProcessXml(root);
    
    		this.delegate = parent;
    	}
    
    /**
    	 * Parse the elements at the root level in the document:
    	 * "import", "alias", "bean".
    	 * @param root the DOM root element of the document
    	 */
    	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)) {
    						parseDefaultElement(ele, delegate);
    					}
    					else {
    						delegate.parseCustomElement(ele);
    					}
    				}
    			}
    		}
    		else {
    			delegate.parseCustomElement(root);
    		}
    	}
    
    	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
    			importBeanDefinitionResource(ele);
    		}
    		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
    			processAliasRegistration(ele);
    		}
    		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
    			processBeanDefinition(ele, delegate);
    		}
    		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
    			// recurse
    			doRegisterBeanDefinitions(ele);
    		}
    	}

     对于默认空间的bean的解析处理如下:

    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    		if (bdHolder != null) {
    			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
    			try {
    				// Register the final decorated instance.
    				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
    			}
    			catch (BeanDefinitionStoreException ex) {
    				getReaderContext().error("Failed to register bean definition with name '" +
    						bdHolder.getBeanName() + "'", ele, ex);
    			}
    			// Send registration event.
    			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    		}
    	}

    通过BeanDefinitionReaderUtils.registerBeanDefinition注册beanDefinition

    /**
    	 * Register the given bean definition with the given bean factory.
    	 * @param definitionHolder the bean definition including name and aliases
    	 * @param registry the bean factory to register with
    	 * @throws BeanDefinitionStoreException if registration failed
    	 */
    	public static void registerBeanDefinition(
    			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    			throws BeanDefinitionStoreException {
    
    		// Register bean definition under primary name.
    		String beanName = definitionHolder.getBeanName();
    		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    
    		// Register aliases for bean name, if any.
    		String[] aliases = definitionHolder.getAliases();
    		if (aliases != null) {
    			for (String alias : aliases) {
    				registry.registerAlias(beanName, alias);
    			}
    		}
    	}
    
    	@Override
    	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 ex) {
    				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    						"Validation of bean definition failed", ex);
    			}
    		}
    
    		BeanDefinition oldBeanDefinition;
    
    		oldBeanDefinition = this.beanDefinitionMap.get(beanName);
    		if (oldBeanDefinition != null) {
    			if (!isAllowBeanDefinitionOverriding()) {
    				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    						"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
    						"': There is already [" + oldBeanDefinition + "] bound.");
    			}
    			else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
    				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
    				if (this.logger.isWarnEnabled()) {
    					this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
    							"' with a framework-generated bean definition: replacing [" +
    							oldBeanDefinition + "] with [" + beanDefinition + "]");
    				}
    			}
    			else if (!beanDefinition.equals(oldBeanDefinition)) {
    				if (this.logger.isInfoEnabled()) {
    					this.logger.info("Overriding bean definition for bean '" + beanName +
    							"' with a different definition: replacing [" + oldBeanDefinition +
    							"] with [" + beanDefinition + "]");
    				}
    			}
    			else {
    				if (this.logger.isDebugEnabled()) {
    					this.logger.debug("Overriding bean definition for bean '" + beanName +
    							"' with an equivalent definition: replacing [" + oldBeanDefinition +
    							"] with [" + beanDefinition + "]");
    				}
    			}
    		}
    		else {
    			//向beanDefinitionNames list中添加beanName
    			this.beanDefinitionNames.add(beanName);
    			this.manualSingletonNames.remove(beanName);
    			this.frozenBeanDefinitionNames = null;
    		}
    		//向beanDefinitionMap中添加beanDefiniton
    		this.beanDefinitionMap.put(beanName, beanDefinition);
    
    		if (oldBeanDefinition != null || containsSingleton(beanName)) {
    			resetBeanDefinition(beanName);
    		}
    	}
  • 相关阅读:
    Weak Event模型
    Dispatcher Queue性能分析
    WPF中ControlTemplate,ItemsPanelTemplate ,DataTemplate
    事件与委托
    DataGrid: 数据项更新并保持多选
    【C#学习笔记】using 三种使用方式
    Python快捷键
    比特率和波特率
    c#winform程序退出的方法
    C#socket通信-----多线程
  • 原文地址:https://www.cnblogs.com/wei-zw/p/8797734.html
Copyright © 2011-2022 走看看