• IOC 初始化源代码阅读之我见


    由于本人的能力有限,只能说出自己的见解,如有错漏什么的,请大家批评指出。

    由于代码封装太多,这里只列出了我认为的部分最重要的代码,一些简单的封装代码,不在下面列出。

    由于代码太过于复杂,在本次博客中,只列出了关键的代码(包含代码在哪个类),具体的所有代码和细节,需要查看源码。
    在源代码解读的时候,关键的方法代码,用红色字体,如:resolvePath(locations[i])。另外,所有具体的实现方法,都是以do开头的。
    IOC容器初始化,包括有定位、加载、注册三个步骤,下面介绍下xml配置方式的IOC容器的生成,通过注解方式生成的原理也是一样,不过要比这个简单些(不需要定位配置文件)。
    ClassPathXmlApplicationContext:这是一个独立的xml的上下文bean,用于将普通的文件路劲加载解释、加载成为对应的bean,配置的路径方式可以是:/myfiles/context.xml 这种方式,也可以是:/myfiles/*-context 这种通配符的方式。

    在ClassPathXmlApplicationContext中,有多个重载的构造方法,最重要的构造方法是:public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)。具体代码如下:
    /**
         * Create a new ClassPathXmlApplicationContext with the given parent,
         * loading the definitions from the given XML files.
         * @param configLocations array of resource locations
         * @param refresh whether to automatically refresh the context,
         * loading all bean definitions and creating all singletons.
         * Alternatively, call refresh manually after further configuring the context.
         * @param parent the parent context
         * @throws BeansException if context creation failed
         * @see #refresh()
         */
        //使用ApplicationContext容器创建一个ClassPathXmlApplicationContext容器,并从给定的xml文件中,加载定义的bean
        public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
                throws BeansException {
    
            super(parent);   //创建一个ApplicationContext 
            setConfigLocations(configLocations);   //为ApplicationContext 设置配置的位置(定位),如果没有设置,则使用默认的配置位置
            if (refresh) {
                refresh();   //刷新容器,这个方法很重要
            }
        }
    
    

    下面介绍下setConfigLocations(configLocations),源代码如下:

    /**
         * Set the config locations for this application context.
    * 为application context设置(一个或多个)配置文件 * <p>If not set, the implementation may use a default as appropriate.
    */ public void setConfigLocations(String... locations) { if (locations != null) { Assert.noNullElements(locations, "Config locations must not be null"); this.configLocations = new String[locations.length]; for (int i = 0; i < locations.length; i++) { this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; } }
    /**
         * Resolve the given path, replacing placeholders with corresponding
         * environment property values if necessary. Applied to config locations.
    * 解析给定的路径,如果必要的话,用相应的环境属性值替换占位符来配置的位置,也就是${......} *
    @param path the original file path * @return the resolved file path * @see org.springframework.core.env.Environment#resolveRequiredPlaceholders(String) */ protected String resolvePath(String path) { return getEnvironment().resolveRequiredPlaceholders(path); }
    //实现方法在orgspringframeworkspring-core4.3.13.RELEASEspring-core-4.3.13.RELEASE-sources.jar!
    //orgspringframeworkcoreenvAbstractPropertyResolver.java类中
    @Override public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException { if (this.strictHelper == null) { this.strictHelper = createPlaceholderHelper(false); } return doResolvePlaceholders(text, this.strictHelper); //真正的实现方法 }
    /**
         * Replaces all placeholders of format {@code ${name}} with the value returned
         * from the supplied {@link PlaceholderResolver}.
    * 替换所有的${name}的占位符 *
    @param value the value containing the placeholders to be replaced * @param placeholderResolver the {@code PlaceholderResolver} to use for replacement * @return the supplied value with placeholders replaced inline */ public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) { Assert.notNull(value, "'value' must not be null"); return parseStringValue(value, placeholderResolver, new HashSet<String>()); }
    protected String parseStringValue(
                String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
    
            StringBuilder result = new StringBuilder(value);
    
            int startIndex = value.indexOf(this.placeholderPrefix);
            while (startIndex != -1) {
                int endIndex = findPlaceholderEndIndex(result, startIndex);
                if (endIndex != -1) {
                    String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
                    String originalPlaceholder = placeholder;
                    if (!visitedPlaceholders.add(originalPlaceholder)) {    //判断是否有闭环调用的占位符
                        throw new IllegalArgumentException(
                                "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
                    }
                    // Recursive invocation, parsing placeholders contained in the placeholder key.
              //递归调用,解析占位符键中包含的占位符。
    placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); // Now obtain the value for the fully resolved key... --现在获得完全解析键的值 String propVal = placeholderResolver.resolvePlaceholder(placeholder); if (propVal == null && this.valueSeparator != null) { int separatorIndex = placeholder.indexOf(this.valueSeparator); if (separatorIndex != -1) { String actualPlaceholder = placeholder.substring(0, separatorIndex); String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length()); propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder); if (propVal == null) { propVal = defaultValue; } } } if (propVal != null) { // Recursive invocation, parsing placeholders contained in the // previously resolved placeholder value.
    //递归调用,解析包含在先前解析的占位符值中的占位符
    propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); if (logger.isTraceEnabled()) { logger.trace("Resolved placeholder '" + placeholder + "'"); } startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length()); } else if (this.ignoreUnresolvablePlaceholders) { // Proceed with unprocessed value. --处理未处理的占位符的值 startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); } else { throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'" + " in value "" + value + """); } visitedPlaceholders.remove(originalPlaceholder); } else { startIndex = -1; } } return result.toString(); }

     跟踪查看,可以看到定位到的是这些形式的字符串:com.abc.model

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    继续跟进,查看 refresh() 方法,如下:

    public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                //刷新前准备工作
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                //通知子类刷新内部bean工厂,这里是抽象工厂模式,就是返回一个factory---在这一步,做了加载的动作,并且也注册了bean定义(这个在代码里的确看到这个
    //)
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. //上下文使用bean工厂前准备工作,包括配置回调函数、不用注册的一些接口,默认的环境bean等一些标准的特性 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. //允许子类中的bean工厂post操作,包括注册WebApplication特殊域如:request、response、sesseion、globalSession、application,还有注册环境bean,还有忽略一些接口 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. //把工厂处理注册为上下文(context)中的bean,如果 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. //注册用于拦截bean创建的bean处理器,会在创建bean实例的时候用于回调 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. //初始化此上下文的消息源 initMessageSource(); // Initialize event multicaster for this context. //为上下文注册多(主机?转换)事件 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. //初始化特定上下文子类中的其他特殊bean registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //实例化所有持有的(非延迟-init)单例 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. //最后一步:发布相应的事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. //销毁已经创建的单例bean,以避免资源浪费 destroyBeans(); // Reset 'active' flag. //重置存活标志 cancelRefresh(ex); // Propagate exception to caller. //抛出异常 throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... //重置spring 中的公共缓存,因为可能永远都不再需要这个bean resetCommonCaches(); } } }

    下面查看 obtainFreshBeanFactory()方法

    /**
         * Tell the subclass to refresh the internal bean factory.
    * 告诉子类刷新内部bean工厂 *
    @return the fresh BeanFactory instance * @see #refreshBeanFactory() * @see #getBeanFactory() */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
    //orgspringframeworkspring-context4.3.13.RELEASEspring-context-4.3.13.RELEASE-sources.jar!orgspringframeworkcontextsupportAbstractRefreshableApplicationContext.java
    
    /**
         * This implementation performs an actual refresh of this context's underlying
         * bean factory, shutting down the previous bean factory (if any) and
         * initializing a fresh bean factory for the next phase of the context's lifecycle.
    *真正地实现对上下文的基础bean工厂执行实际的刷新,如果之前有了工厂,则关闭前一个bean工厂,并为上下文生命周期的下一阶段初始化一个新的bean工厂。
    */ @Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); //销毁bean closeBeanFactory(); //关闭bean工厂 } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId());
    //这里允许自定义bean工厂 customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory);
    synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
    //orgspringframeworkspring-context4.3.13.RELEASEspring-context-4.3.13.RELEASE-sources.jar!orgspringframeworkcontextsupportAbstractXmlApplicationContext.java
    
    /**
         * Loads the bean definitions via an XmlBeanDefinitionReader.
    * 通过XmlBeanDefinitionReader装载bean定义 *
    @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader * @see #initBeanDefinitionReader * @see #loadBeanDefinitions */ @Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment.
            beanDefinitionReader.setEnvironment(this.getEnvironment());   
    //环境类:ConfigurableEnvironment ,默认实现是AbstractEnvironment(这个类很重要)
    //这里面,有几个方法很有意思,就是的一些配置文件的实现。包括默认的配置文件读取,配置文件的非法字符串比如!等,空格处理,活跃配置文件等
    
    //读取配置文件,特别地:spring.profiles.active 这个就是在application.properties中设置的spring.profiles.active=xxx 的那个实现
    
    protected Set<String> doGetActiveProfiles() {
            Set var1 = this.activeProfiles;
            synchronized(this.activeProfiles) {
                if (this.activeProfiles.isEmpty()) {
                    String profiles = this.getProperty("spring.profiles.active");
                    if (StringUtils.hasText(profiles)) {
                        this.setActiveProfiles(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(profiles)));
                    }
                }
    
                return this.activeProfiles;
            }
        }
    
    
    
     
            beanDefinitionReader.setResourceLoader(this);
    //设置用于解析的SAX实体解析器 beanDefinitionReader.setEntityResolver(
    new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); }
    /**
         * Load the bean definitions with the given XmlBeanDefinitionReader.
    * 使用给定的xmlBeanDefinitionReader加载Bean 定义 * <p>The lifecycle of the bean factory is handled by the {
    @link #refreshBeanFactory} * method; hence this method is just supposed to load and/or register bean definitions. * @param reader the XmlBeanDefinitionReader to use * @throws BeansException in case of bean registration errors * @throws IOException if the required XML document isn't found * @see #refreshBeanFactory * @see #getConfigLocations * @see #getResources * @see #getResourcePatternResolver */ protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {

             //读取xml,比如:new ClassPathXmlApplicationContext("classpath:multi-datasource.xml"); 这样定义的

            Resource[] configResources = getConfigResources();
            if (configResources != null) {
                reader.loadBeanDefinitions(configResources);
            }
            String[] configLocations = getConfigLocations();
            if (configLocations != null) {
                reader.loadBeanDefinitions(configLocations);
            }
        }
    // 这里使用循环,证明可以加载多个配置文件
    @Override
    public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int counter = 0; for (Resource resource : resources) { counter += loadBeanDefinitions(resource); } return counter; }
    //orgspringframeworkspring-beans4.3.13.RELEASEspring-beans-4.3.13.RELEASE-sources.jar!orgspringframeworkeansfactorygroovyGroovyBeanDefinitionReader.java
    /**
    * Load bean definitions from the specified Groovy script or XML file.
    * 从指定的Groovy脚本或XML文件加载bean定义 * <p>Note that {
    @code ".xml"} files will be parsed as XML content; all other kinds * of resources will be parsed as Groovy scripts. * @param resource the resource descriptor for the Groovy script or XML file * @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors */ public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); }
    /**
         * Load bean definitions from the specified Groovy script or XML file.
    * 从指定的Groovy脚本或XML文件加载bean定义 * <p>Note that {
    @code ".xml"} files will be parsed as XML content; all other kinds * of resources will be parsed as Groovy scripts. * @param encodedResource the resource descriptor for the Groovy script or XML file, * allowing specification of an encoding to use for parsing the file * @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors */ public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { // Check for XML files and redirect them to the "standard" XmlBeanDefinitionReader String filename = encodedResource.getResource().getFilename(); if (StringUtils.endsWithIgnoreCase(filename, ".xml")) { return this.standardXmlBeanDefinitionReader.loadBeanDefinitions(encodedResource); } Closure beans = new Closure(this) { public Object call(Object[] args) { invokeBeanDefiningClosure((Closure) args[0]); return null; } }; Binding binding = new Binding() { @Override public void setVariable(String name, Object value) { if (currentBeanDefinition != null) { applyPropertyToBeanDefinition(name, value); } else { super.setVariable(name, value); } } }; binding.setVariable("beans", beans); int countBefore = getRegistry().getBeanDefinitionCount(); try { GroovyShell shell = new GroovyShell(getResourceLoader().getClassLoader(), binding); shell.evaluate(encodedResource.getReader(), "beans"); } catch (Throwable ex) { throw new BeanDefinitionParsingException(new Problem("Error evaluating Groovy script: " + ex.getMessage(), new Location(encodedResource.getResource()), null, ex)); } return getRegistry().getBeanDefinitionCount() - countBefore; }
    /**
         * Load bean definitions from the specified XML file.
    * 从指定的xml文件中加载bean definition *
    @param encodedResource the resource descriptor for the XML file, * allowing to specify an encoding to use for parsing the file
    * 允许指定编码格式,用于转换xml文件,比如:UTF-8 *
    @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors */ public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isInfoEnabled()) { logger.info("Loading XML bean definitions from " + encodedResource.getResource()); } Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<EncodedResource>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); }
    // 检测是否有循环(闭环)导入
    if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try {
    //读取文件 InputStream inputStream
    = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream);
    // 设置encoding
    if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally {
    //关闭流 inputStream.close(); } }
    catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } }
    /**
         * Actually load bean definitions from the specified XML file.
    * 从指定的xml文件中,实际执行加载bean定义的方法 *
    @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 {
    //读取xml文件 Document doc
    = doLoadDocument(inputSource, resource); return registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException ex) { throw ex; } catch (SAXParseException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex); } catch (SAXException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", ex); } catch (ParserConfigurationException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, ex); } catch (IOException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, ex); } catch (Throwable ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, ex); } }
    /**
         * Register the bean definitions contained in the given DOM document.    --注册包含在给定的dom中的bean定义
         * 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 documentReader = createBeanDefinitionDocumentReader();
            int countBefore = getRegistry().getBeanDefinitionCount();
            documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
            return getRegistry().getBeanDefinitionCount() - countBefore;
        }
    //orgspringframeworkspring-beans4.3.13.RELEASEspring-beans-4.3.13.RELEASE-sources.jar!orgspringframeworkeansfactoryxmlDefaultBeanDefinitionDocumentReader.java
    
    /**
         * This implementation parses bean definitions according to the "spring-beans" XSD
    * 根据“spring-beans”XSD解析bean定义 * (or DTD, historically). * <p>Opens a DOM Document; then initializes the default settings * specified at the {
    @code <beans/>} level; then parses the contained bean definitions. */ @Override public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); Element root = doc.getDocumentElement(); doRegisterBeanDefinitions(root); }/**
         * Register each bean definition within the given root {@code <beans/>} element.
    * 注册根节点内的每一个bean定义
    */ protected void doRegisterBeanDefinitions(Element root) { // Any nested <beans> elements will cause recursion in this method. In // order to propagate and preserve <beans> default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent);
    //如果xml 是这种格式开头的,这就是我们平时自定义的xml文件。http://www.springframework.org/schema/beans
    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)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } }
    //预处理xml,默认实现为空。可以自定义xml解释,通过扩展这个方法,实现在bean definition的加载之前,先加载哪个元素 preProcessXml(root); parseBeanDefinitions(root,
    this.delegate);

    //后置处理xml,默认实现为空。可以自定义xml的解释,通过扩展这个方法,实现bean definition后,处理任何自定义元素 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;
    //判断是否是默认的命名空间:http://www.springframework.org/schema/beans,一般情况下我们都是放在这个命名空间下
    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)) {   //import 标签
                importBeanDefinitionResource(ele);
            }
            else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {   //alias标签
                processAliasRegistration(ele);
            }
            else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {    //bean 标签
                processBeanDefinition(ele, delegate);
            }
            else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {    //beans标签。注意,这里有递归调用。这里实际上也调用了上面的processBeanDefinition方法
                // recurse
                doRegisterBeanDefinitions(ele);
            }
        }
    /**
         * Process the given bean element, parsing the bean definition   --处理给定的bean 元素,转换并注册到注册中心
         * and registering it with the registry.
         */
        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));
            }
        }
    /**
         * Parses the supplied {@code <bean>} element. May return {@code null}
         * if there were errors during parse. Errors are reported to the
         * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
         */
        public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
            return parseBeanDefinitionElement(ele, null);
        }
    
        /**
         * Parses the supplied {@code <bean>} element. May return {@code null}
         * if there were errors during parse. Errors are reported to the
         * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
         */
        public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
            String id = ele.getAttribute(ID_ATTRIBUTE);
            String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
    
            List<String> aliases = new ArrayList<String>();
            if (StringUtils.hasLength(nameAttr)) {
                String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                aliases.addAll(Arrays.asList(nameArr));
            }
    
            String beanName = id;
            if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
                beanName = aliases.remove(0);
                if (logger.isDebugEnabled()) {
                    logger.debug("No XML 'id' specified - using '" + beanName +
                            "' as bean name and " + aliases + " as aliases");
                }
            }
    
            if (containingBean == null) {
                checkNameUniqueness(beanName, aliases, ele);
            }
    
            AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
            if (beanDefinition != null) {
                if (!StringUtils.hasText(beanName)) {
                    try {
                        if (containingBean != null) {
                            beanName = BeanDefinitionReaderUtils.generateBeanName(
                                    beanDefinition, this.readerContext.getRegistry(), true);
                        }
                        else {
                            beanName = this.readerContext.generateBeanName(beanDefinition);
                            // Register an alias for the plain bean class name, if still possible,
                            // if the generator returned the class name plus a suffix.
                            // This is expected for Spring 1.2/2.0 backwards compatibility.
                            String beanClassName = beanDefinition.getBeanClassName();
                            if (beanClassName != null &&
                                    beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                                    !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                                aliases.add(beanClassName);
                            }
                        }
                        if (logger.isDebugEnabled()) {
                            logger.debug("Neither XML 'id' nor 'name' specified - " +
                                    "using generated bean name [" + beanName + "]");
                        }
                    }
                    catch (Exception ex) {
                        error(ex.getMessage(), ele);
                        return null;
                    }
                }
                String[] aliasesArray = StringUtils.toStringArray(aliases);
                return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
            }
    
            return null;
        }
    /**
         * Parse the bean definition itself, without regard to name or aliases. May return 
    * 解析bean定义本身,而不考虑名称或别名 * {
    @code null} if problems occurred during the parsing of the bean definition. */ public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); String className = null; if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } try { String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); } AbstractBeanDefinition bd = createBeanDefinition(className, parent);
    //将给定bean元素的属性应用于给定bean *定义,如:singleton、scope、abstract、lazy-init 等属性 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
    //设置描述为可阅读 bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
    //设置元数据属性 parseMetaElements(ele, bd);
    //解析查找覆盖给定bean元素的子元素 parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
    //解释给定的bean的子元素的替换方法 parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
    //解释给定bean元素的构造函数的子元素 parseConstructorArgElements(ele, bd);
    //解释给定的bean元素的子元素的属性 parsePropertyElements(ele, bd);
    //解释给定的bean元素的子元素的限定符 parseQualifierElements(ele, bd);
    //设置bean定义的来源 bd.setResource(this.readerContext.getResource()); bd.setSource(extractSource(ele));
    return bd; } catch (ClassNotFoundException ex) { error("Bean class [" + className + "] not found", ele, ex); } catch (NoClassDefFoundError err) { error("Class that bean class [" + className + "] depends on not found", ele, err); } catch (Throwable ex) { error("Unexpected failure during bean definition parsing", ele, ex); } finally { this.parseState.pop(); } return null; }

     下面贴出加载xml文件中的属性配置的源代码

    /**
         * Parse property sub-elements of the given bean element.
         */
        public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
            NodeList nl = beanEle.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
                    parsePropertyElement((Element) node, bd);
                }
            }
        }
    /**
         * Parse a property element.
         */
        public void parsePropertyElement(Element ele, BeanDefinition bd) {
            String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
            if (!StringUtils.hasLength(propertyName)) {
                error("Tag 'property' must have a 'name' attribute", ele);
                return;
            }
            this.parseState.push(new PropertyEntry(propertyName));
            try {
                if (bd.getPropertyValues().contains(propertyName)) {
                    error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
                    return;
                }
                Object val = parsePropertyValue(ele, bd, propertyName);
                PropertyValue pv = new PropertyValue(propertyName, val);
                parseMetaElements(ele, pv);
                pv.setSource(extractSource(ele));
                bd.getPropertyValues().addPropertyValue(pv);
            }
            finally {
                this.parseState.pop();
            }
        }
    /**
         * Get the value of a property element. May be a list etc.
         * Also used for constructor arguments, "propertyName" being null in this case.
         */
        public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
            String elementName = (propertyName != null) ?
                            "<property> element for property '" + propertyName + "'" :
                            "<constructor-arg> element";
    
            // Should only have one child element: ref, value, list, etc.
            NodeList nl = ele.getChildNodes();
            Element subElement = null;
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
                        !nodeNameEquals(node, META_ELEMENT)) {
                    // Child element is what we're looking for.
                    if (subElement != null) {
                        error(elementName + " must not contain more than one sub-element", ele);
                    }
                    else {
                        subElement = (Element) node;
                    }
                }
            }
    
            boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
            boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
            if ((hasRefAttribute && hasValueAttribute) ||
                    ((hasRefAttribute || hasValueAttribute) && subElement != null)) {
                error(elementName +
                        " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
            }
    
            if (hasRefAttribute) {
                String refName = ele.getAttribute(REF_ATTRIBUTE);
                if (!StringUtils.hasText(refName)) {
                    error(elementName + " contains empty 'ref' attribute", ele);
                }
                RuntimeBeanReference ref = new RuntimeBeanReference(refName);
                ref.setSource(extractSource(ele));
                return ref;
            }
            else if (hasValueAttribute) {
                TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
                valueHolder.setSource(extractSource(ele));
                return valueHolder;
            }
            else if (subElement != null) {
                return parsePropertySubElement(subElement, bd);
            }
            else {
                // Neither child element nor "ref" or "value" attribute found.
                error(elementName + " must specify a ref or value", ele);
                return null;
            }
        }
    public Object parsePropertySubElement(Element ele, BeanDefinition bd) {
            return parsePropertySubElement(ele, bd, null);
        }
    
        /**
         * Parse a value, ref or collection sub-element of a property or
         * constructor-arg element.
         * @param ele subelement of property element; we don't know which yet
         * @param defaultValueType the default type (class name) for any
         * {@code <value>} tag that might be created
         */
        public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) {
            if (!isDefaultNamespace(ele)) {
                return parseNestedCustomElement(ele, bd);
            }
            else if (nodeNameEquals(ele, BEAN_ELEMENT)) {
                BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd);
                if (nestedBd != null) {
                    nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd);
                }
                return nestedBd;
            }
            else if (nodeNameEquals(ele, REF_ELEMENT)) {
                // A generic reference to any name of any bean.
                String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);
                boolean toParent = false;
                if (!StringUtils.hasLength(refName)) {
                    // A reference to the id of another bean in the same XML file.
                    refName = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
                    if (!StringUtils.hasLength(refName)) {
                        // A reference to the id of another bean in a parent context.
                        refName = ele.getAttribute(PARENT_REF_ATTRIBUTE);
                        toParent = true;
                        if (!StringUtils.hasLength(refName)) {
                            error("'bean', 'local' or 'parent' is required for <ref> element", ele);
                            return null;
                        }
                    }
                }
                if (!StringUtils.hasText(refName)) {
                    error("<ref> element contains empty target attribute", ele);
                    return null;
                }
                RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);
                ref.setSource(extractSource(ele));
                return ref;
            }
            else if (nodeNameEquals(ele, IDREF_ELEMENT)) {
                return parseIdRefElement(ele);
            }
            else if (nodeNameEquals(ele, VALUE_ELEMENT)) {
                return parseValueElement(ele, defaultValueType);
            }
            else if (nodeNameEquals(ele, NULL_ELEMENT)) {
                // It's a distinguished null value. Let's wrap it in a TypedStringValue
                // object in order to preserve the source location.
                TypedStringValue nullHolder = new TypedStringValue(null);
                nullHolder.setSource(extractSource(ele));
                return nullHolder;
            }
            else if (nodeNameEquals(ele, ARRAY_ELEMENT)) {
                return parseArrayElement(ele, bd);
            }
            else if (nodeNameEquals(ele, LIST_ELEMENT)) {
                return parseListElement(ele, bd);
            }
            else if (nodeNameEquals(ele, SET_ELEMENT)) {
                return parseSetElement(ele, bd);
            }
            else if (nodeNameEquals(ele, MAP_ELEMENT)) {
                return parseMapElement(ele, bd);
            }
            else if (nodeNameEquals(ele, PROPS_ELEMENT)) {
                return parsePropsElement(ele);
            }
            else {
                error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele);
                return null;
            }
        }

    从上面可以看到,xml中支持的map、list、set、props、array这些属性,都是在这里方法中进行最终的处理。以上的代码,是比较关键的加载bean的代码。

    值得注意的是,bean定义是注册到一个Map中的,也就是说,IOC容器的本质,是一个Map。如下:

    /** Map of bean definition objects, keyed by bean name */
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);

    --orgspringframeworkspring-beans5.0.9.RELEASEspring-beans-5.0.9.RELEASE-sources.jar!orgspringframeworkeansfactorysupportSimpleBeanDefinitionRegistry.java

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    下面阅读 invokeBeanFactoryPostProcessors(beanFactory)

    /**
         * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
         * respecting explicit order if given.
         * <p>Must be called before singleton instantiation.
         */

    //初始化bean并执行所有已经注册bean工厂后置处理器,如果有排序,则按照排序进行处理华
    //这里要注意的:必须在单例bean的实例化之前执行这个bean工厂的初始化,因为单例模式是程序运行的时候就已经创建,而普通bean则是在调用时候,才会初始化 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
    public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<String>();
    
    //如果是注册的工厂bean,则先于普通的bean先初始化
    if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest.

    //
    不要在这里初始化factorybean:因为需要保证所有的普通的bean在后置处理器中使用到(我想应该是调用的时候会用到吧,这个不确定)

    List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
                // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    // 首先,先初始化实现(使用)
    PriorityOrdered接口的bean
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();  //这里有清理动作,也就是设置为null
    
                // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    // 接下来,执行实现了Ordered接口的注册(性质)的后置工厂处理器
    //从实现细节里可以看出集成了Comparator 接口,并且是从小到大排序。也就是说,@Order的value越小,越早注入容器,实现初始化 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
    //最后,执行所有其他的注册(性质的)bean工厂后置处理器
    boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance.
    // 执行上下文注册的工厂后置处理器,我们自定义的bean就是在这一步执行
    invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest.
    // 平时使用@Order这个注解,就是在这里发生作用。
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); List<String> orderedPostProcessorNames = new ArrayList<String>(); List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //先加载Priority类的 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { //再加载Order类的 orderedPostProcessorNames.add(ppName); } else { //最后加载没有Order的 nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }

    上面要注意几点:1、执行初始化工厂后置处理器,不会实例化已加载定义的bean  2、初始化工厂后置处理器,必须在单例bean的实例化之前,因为单例bean是运行时候就已经实例化  3、初始化的执行,是有顺序的

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    下面阅读 registerBeanPostProcessors(beanFactory)

    /**
         * Instantiate and invoke all registered BeanPostProcessor beans,
         * respecting explicit order if given.
         * <p>Must be called before any instantiation of application beans.
         */
    //初始化并执行所有已注册的bean后置处理器bean,如果有排序,则按照排序进行初始化和执行。
    //必须在任何上下文bean实例化之前调用,因为实例化是从register从取出对应的bean的
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); //这里是个委派模式 }
    public static void registerBeanPostProcessors(
                ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    
            String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
            // Register BeanPostProcessorChecker that logs an info message when
            // a bean is created during BeanPostProcessor instantiation, i.e. when
            // a bean is not eligible for getting processed by all BeanPostProcessors.
    //
    注册BeanPostProcessorChecker,它记录信息消息bean是在BeanPostProcessor实例化期间创建的,
    //bean 是在实例化的过程中创建的,也就是任何时候创建。
    //bean 没有资格被所有beanpostprocessor处理
            int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
            beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
            // Separate between BeanPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
            List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
            List<String> orderedPostProcessorNames = new ArrayList<String>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                    priorityOrderedPostProcessors.add(pp);
                    if (pp instanceof MergedBeanDefinitionPostProcessor) {
                        internalPostProcessors.add(pp);
                    }
                }
                else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            // First, register the BeanPostProcessors that implement PriorityOrdered.
    //首先,注册实现 PriorityOrdered 的BeanPostProcessors ---这些顺序是不是很熟悉 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered.
    //然后,注册实现Ordered的BeanPostProcessors List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors.
    // 注册所有规律的BeanProstProcessors List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors.
    // 重注册所有的内部bean后置处理器---这里没有为什么,就是这样设计的
    sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc).
    //重新注册后处理器以检测内部bean作为applicationlistener,将其移动到处理器链的末尾(用于获取代理等)
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }

    上面这段代码,跟invokeBeanFactoryPostProcessors(beanFactory) 很像是吧。惊不惊喜,意不意外!

    Override
        public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
            Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
            this.beanPostProcessors.remove(beanPostProcessor);
            this.beanPostProcessors.add(beanPostProcessor);
            if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
                this.hasInstantiationAwareBeanPostProcessors = true;
            }
            if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
                this.hasDestructionAwareBeanPostProcessors = true;
            }
        }
    /** BeanPostProcessors to apply in createBean */
        private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();

    查看这个addProcessor,其实就是在一个list里面先remove,然后add

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------

    到目前为止,已经阅读完所有的关键代码。当然了,由于本人水平有限,也是第一次阅读这个代码,中间肯定有很多理解不到位,甚至错误的地方,请各位大神批评指正。欢迎留言交流。

  • 相关阅读:
    firefox、chrome的DNS缓存清除方法
    MySQL中查询所有数据库占用磁盘空间大小和单个库中所有表的大小的sql语句
    PHP获取当前页面的网址
    JAVA接单10大平台
    线程
    创建一个简单的迭代器
    2016-09-20
    C# 静态构造函数
    ASP.NET MVC 右键点击添加没有区域(Area)、控制器、试图等选项
    Git的使用--如何将本地项目上传到Github(两种简单、方便的方法)
  • 原文地址:https://www.cnblogs.com/drafire/p/9564772.html
Copyright © 2020-2023  润新知