Spring源码—初识IOC

👽System.out.println(“👋🏼嗨,大家好,我是代码不会敲的小符,双非大四,Java实习中…”);
📚System.out.println(“🎈如果文章中有错误的地方,恳请大家指正!共同进步,共同成长✊”);
🌟System.out.println(“💡如果文章对您有所帮助,希望您可以三连支持一下博主噢🔥”);
🌈System.out.println("🚀正在完成计划中:接下来的三个月里,对梦想的追逐 ");

初识Spring源码

    • ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml"); 这句代码发生了什么?
    • ClassPathXmlApplicationContext构造方法
      • 调用父类构造方法super(parent)
      • 配置文件路径 this.setConfigLocations(configLocations)
      • 核心方法-入口:refresh
    • 1.3.1 prepareRefresh 方法
    • 1.3.2 obtainFreshBeanFactory 方法
      • 1.3.2.1 refreshBeanFactory 方法
      • 1.3.2.1.1 hasBeanFactory 方法
      • 1.3.2.1.2 destroyBeans 方法
      • 1.3.2.1.3 closeBeanFactory 方法
      • 1.3.2.1.4 creatBeanFactory 方法
      • 1.3.2.1.5 customizeBeanFactory 方法
      • 1.3.2.1.6 loadBeanDefinitions 方法
        • 1.3.2.1.6.1 XmlBeanDefinitionReader 构造方法
        • 1.3.2.1.6.2 beanDefinitionReader.setEntityResolver
        • **1.3.2.1.6.3 initBeanDefinitionReader**
        • 1.3.2.1.6.4 loadBeanDefinitions
        • 1.3.2.1.6.4.1 doLoadBeanDefinitions
        • 1.3.2.1.6.4.1-1 doLoadBeanDefinitions
        • 1.3.2.1.6.4.1-2 registerBeanDefinitions
    • 1.3.3 prepareBeanFactory 方法
    • 1.3.4 postProcessBeanFactory 方法
    • 1.3.5 invokeBeanFactoryPostProcessors
    • 1.3.6 registerBeanPostProcessors 方法
    • 1.3.7 initMessageSource方法
    • 1.3.8 initApplicationEventMulticaster 方法
    • 1.3.9 onRefresh 方法
    • 1.3.10 registerListeners 方法
    • 1.3.11 finishBeanFactoryInitialization 方法
    • 1.3.12 finishRefresh 方法
    • 1.3.13 resetCommonCaches 方法


还没有补充完成…

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“application.xml”); 这句代码发生了什么?

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean {
    ...
}

sax,dom4j解析xml文件
dtd、xsd是用来定义xml文档验证和文档规范的两种技术(.schemas:映射到本地文件进行解析)
注意:debug时idea是调用的是toString方法

ClassPathXmlApplicationContext构造方法

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[]{configLocation}, true, (ApplicationContext)null);
    }
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
        super(parent);
        this.setConfigLocations(configLocations);
        if (refresh) {
            this.refresh();
        }

    }

调用父类构造方法super(parent)

  • 资源模式管理器 getResourcePatternResolver()=new PathMatchingResourcePatternSolver 用来解析xml配置文件
    public AbstractApplicationContext() {
        this.logger = LogFactory.getLog(this.getClass());
        this.id = ObjectUtils.identityToString(this);
        this.displayName = ObjectUtils.identityToString(this);
        this.beanFactoryPostProcessors = new ArrayList();
        this.active = new AtomicBoolean();
        this.closed = new AtomicBoolean();
        this.startupShutdownMonitor = new Object();
        this.applicationListeners = new LinkedHashSet();
        this.resourcePatternResolver = this.getResourcePatternResolver();
    }

配置文件路径 this.setConfigLocations(configLocations)

    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] = this.resolvePath(locations[i]).trim();
            }
        } else {
            this.configLocations = null;
        }

    }

核心方法-入口:refresh

当调用了refresh()方法时,Spring容器会进行一系列的操作来确保容器的状态是最新的,并且所有的bean都已经被正确初始化和准备就绪;确保了容器的状态和所有bean的准备工作。

  1. 准备工作: 清理之前的bean定义,重置资源加载器等。
  2. 加载bean定义: 根据配置文件或者注解等方式,加载和解析bean的定义信息。
  3. 注册bean定义: 将加载的bean定义注册到BeanDefinitionRegistry中,这是Spring容器中管理bean定义的地方。
  4. 预实例化单例bean: 实例化并初始化所有在配置文件中定义的单例bean。
  5. **完成刷新工作: **完成刷新过程,通知相关的监听器等。
  • startupShutdownMonitor 同步监视器
    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

1.3.1 prepareRefresh 方法

容器刷新前的准备工作

  1. 设置容器的启动时间
  2. 设置容器活跃状态为true
  3. 设置容器关闭状态为false
  4. 获取Environment对象,并加载当前系统的属性值到Environment对象中
  5. 准备监听器和事件的集合对象-默认为空的集合
  • initPropertySources 可以用来扩展操作:自定义设置环境变量属性值
    protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        if (this.logger.isInfoEnabled()) {
            this.logger.info("Refreshing " + this);
        }

        this.initPropertySources();
        this.getEnvironment().validateRequiredProperties();
        this.earlyApplicationEvents = new LinkedHashSet();
    }

    protected void initPropertySources() {
    }

1.3.2 obtainFreshBeanFactory 方法

创建容器对象:DefaultLisrtableBeanFactory
加载Xml配置文件的属性值到当前工厂中:BeanDefinition

  • refreshBeanFactory:初始化BeanFactory。进行Xml文件读取,将得到的BeanFactory记录在当前实体属性中
  • getBeanFactory:返回当前实体的beanFactory属性
    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 abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
    public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

1.3.2.1 refreshBeanFactory 方法

初始化BeanFactory。进行Xml文件读取,将得到的BeanFactory记录在当前实体属性中

  1. 通过我们传递的xml 文件的路径,利用 documentLoader 将其封装成 Document 格式
  2. 创建 BeanDefinitionDocumentReader 来正式解析 xml 文件并找到文件的 root
  3. 根据 root 扫描遍历,对不同配置的标签(import、alias、bean、beans)走不同的逻辑判断
  4. 将当前的标签各属性进行组装成 beanDefinition,调用 DefaultListableBeanFactory 进行注册
  5. 根据 BeanName 查询该 beanDefinition 是否被注册过,如果被注册过,则直接抛出异常(Spring不允许覆盖)
  6. 如果没有注册过,则将 BeanName 与 beanDefinition 注册至 DefaultListableBeanFactory 的 beanDefinitionMap 中
  7. 最后,如果该 beanDefinition 含有别名,也要将别名进行注册
/**
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {...}
*/
protected final void refreshBeanFactory() throws BeansException {
	// 为什么这样??因为启动过程中可能有beanFactory
    if (this.hasBeanFactory()) {
        this.destroyBeans();
        this.closeBeanFactory();
    }
    
    try {
        DefaultListableBeanFactory beanFactory = this.createBeanFactory();
        // 设置序列号指定id,可以从id反序列化到beanFactory对象
        beanFactory.setSerializationId(this.getId());
        this.customizeBeanFactory(beanFactory);
        this.loadBeanDefinitions(beanFactory);
        synchronized(this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    } catch (IOException var5) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
    }
}
/**
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {...}
*/
    protected final void refreshBeanFactory() throws IllegalStateException {
        if (!this.refreshed.compareAndSet(false, true)) {
            throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
        } else {
            this.beanFactory.setSerializationId(this.getId());
        }
    }

1.3.2.1.1 hasBeanFactory 方法

为什么这样??因为启动过程中可能有beanFactory


	protected final boolean hasBeanFactory() {
        synchronized(this.beanFactoryMonitor) {
            return this.beanFactory != null;
        }
    }

1.3.2.1.2 destroyBeans 方法

	protected void destroyBeans() {
        this.getBeanFactory().destroySingletons();
    }
	/**     public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry 
    		void destroySingletons(); 
    */
	/**1.  public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
            public void destroySingletons() {
                super.destroySingletons();
                this.factoryBeanObjectCache.clear();
            }

	*/
	/** 2. 注: abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport
    abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
    class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
    	public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

            public void destroySingletons() {
                super.destroySingletons();
                this.manualSingletonNames.clear();
                this.clearByTypeCache();
            }
                    private void clearByTypeCache() {
                        this.allBeanNamesByType.clear();
                        this.singletonBeanNamesByType.clear();
                    }

    */


// public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// super.destroySingletons() 最终都执行了下面的这个方法
	public void destroySingletons() {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Destroying singletons in " + this);
        }

        synchronized(this.singletonObjects) {
            this.singletonsCurrentlyInDestruction = true;
        }

        String[] disposableBeanNames;
        synchronized(this.disposableBeans) {
            disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
        }

        for(int i = disposableBeanNames.length - 1; i >= 0; --i) {
            this.destroySingleton(disposableBeanNames[i]);
        }

        this.containedBeanMap.clear();
        this.dependentBeanMap.clear();
        this.dependenciesForBeanMap.clear();
        synchronized(this.singletonObjects) {
            this.singletonObjects.clear();
            this.singletonFactories.clear();
            this.earlySingletonObjects.clear();
            this.registeredSingletons.clear();
            this.singletonsCurrentlyInDestruction = false;
        }
    }
	public void destroySingleton(String beanName) {
        this.removeSingleton(beanName);
        DisposableBean disposableBean;
        synchronized(this.disposableBeans) {
            disposableBean = (DisposableBean)this.disposableBeans.remove(beanName);
        }

        this.destroyBean(beanName, disposableBean);
    }

    protected void destroyBean(String beanName, DisposableBean bean) {
        Set<String> dependencies = (Set)this.dependentBeanMap.remove(beanName);
        if (dependencies != null) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
            }

            Iterator var4 = dependencies.iterator();

            while(var4.hasNext()) {
                String dependentBeanName = (String)var4.next();
                this.destroySingleton(dependentBeanName);
            }
        }

        if (bean != null) {
            try {
                bean.destroy();
            } catch (Throwable var10) {
                this.logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", var10);
            }
        }

        Set<String> containedBeans = (Set)this.containedBeanMap.remove(beanName);
        if (containedBeans != null) {
            Iterator var13 = containedBeans.iterator();

            while(var13.hasNext()) {
                String containedBeanName = (String)var13.next();
                this.destroySingleton(containedBeanName);
            }
        }

        synchronized(this.dependentBeanMap) {
            Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator();

            while(true) {
                if (!it.hasNext()) {
                    break;
                }

                Map.Entry<String, Set<String>> entry = (Map.Entry)it.next();
                Set<String> dependenciesToClean = (Set)entry.getValue();
                dependenciesToClean.remove(beanName);
                if (dependenciesToClean.isEmpty()) {
                    it.remove();
                }
            }
        }

        this.dependenciesForBeanMap.remove(beanName);
    }

1.3.2.1.3 closeBeanFactory 方法

    protected final void closeBeanFactory() {
        synchronized(this.beanFactoryMonitor) {
            this.beanFactory.setSerializationId((String)null);
            this.beanFactory = null;
        }
    }

1.3.2.1.4 creatBeanFactory 方法

创建DefaultListableBeanFactory对象

 // DefaultListableBeanFactory beanFactory = this.createBeanFactory();
protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
    }

1.3.2.1.5 customizeBeanFactory 方法

制化beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖

  • **allowBeanDefinitionOverriding:**如果属性值不为 null,则将 beanFactory 的 allowBeanDefinitionOverriding 属性设置为该值。这个属性用于指示是否允许覆盖(overriding)已存在的同名 bean 定义。默认设置为 true,允许覆盖;如果设置为 false,则不允许覆盖。
  • **allowCircularReferences:**如果属性值不为 null,则将 beanFactory 的 allowCircularReferences 属性设置为该值。这个属性用于指示是否允许循环引用(circular references)的存在。默认设置为 true,允许循环引用;如果设置为 false,则不允许循环引用。
  • 如何设置为false?? 重写customizeBeanFactory方法
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        if (this.allowBeanDefinitionOverriding != null) {
            beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }

        if (this.allowCircularReferences != null) {
            beanFactory.setAllowCircularReferences(this.allowCircularReferences);
        }

    }

1.3.2.1.6 loadBeanDefinitions 方法

初始化documentReader,并进行XML文件读取及解析

  1. 创建一个beanDefinitionReader对象实例,并通过回调设置到beanFactory中
  2. 给reader对象设置环境对象,方便对某些值进行替换操作,例如:${username} 是环境属性
  3. 设置资源加载器
  4. 设置实体处理器(dtd解析、schema文件读取:xsd解析)
  5. 初始化beanDefinitionReader对象,并设置配置文件是否要验证(默认是true)
  6. 开始完成bean的加载

注意:doxxx方法才是实际干活的方法

    protected abstract void loadBeanDefinitions(DefaultListableBeanFactory var1) throws BeansException, IOException;

// AbstractXmlApplicationContext.loadBeanDefinitions
// 用了适配器设计模式
    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);
    }

1.3.2.1.6.1 XmlBeanDefinitionReader 构造方法

// public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {...}
    public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
        super(registry);
        this.errorHandler = new SimpleSaxErrorHandler(this.logger);
        this.validationModeDetector = new XmlValidationModeDetector();
        this.resourcesCurrentlyBeingLoaded = new NamedThreadLocal("XML bean definition resources currently being loaded");
    }

// public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable, BeanDefinitionReader {...}
   protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        this.registry = registry;
        if (this.registry instanceof ResourceLoader) {
            this.resourceLoader = (ResourceLoader)this.registry;
        } else {
            this.resourceLoader = new PathMatchingResourcePatternResolver();
        }

        if (this.registry instanceof EnvironmentCapable) {
            this.environment = ((EnvironmentCapable)this.registry).getEnvironment();
        } else {
            this.environment = new StandardEnvironment();
        }

    }

1.3.2.1.6.2 beanDefinitionReader.setEntityResolver

设置实体处理器
(dtd解析、schema文件读取:xsd解析)

// class ResourceEntityResolver extends DelegatingEntityResolver
public ResourceEntityResolver(ResourceLoader resourceLoader) {
		super(resourceLoader.getClassLoader());
		this.resourceLoader = resourceLoader;
	}

下一步↓

// class DelegatingEntityResolver implements EntityResolver
public DelegatingEntityResolver(ClassLoader classLoader) {
        this.dtdResolver = new BeansDtdResolver();
        this.schemaResolver = new PluggableSchemaResolver(classLoader);
    }

1.3.2.1.6.3 initBeanDefinitionReader

配置文件是否验证,默认是true:验证

    protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
        reader.setValidating(this.validating);
    }

1.3.2.1.6.4 loadBeanDefinitions

套娃:重加载

  1. 以resource的形式获取配置文件的资源位置(一般用不到,取决于启动类的传参格式)
  2. 以String的形式获取配置文件的位置
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        Resource[] configResources = this.getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }

        String[] configLocations = this.getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }

    }

下一步↓

    // reader.loadBeanDefinitions(configLocations);
	public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
        Assert.notNull(locations, "Location array must not be null");
        int counter = 0;
        String[] var3 = locations;
        int var4 = locations.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String location = var3[var5];
            counter += this.loadBeanDefinitions(location);
        }

        return counter;
    }

下一步↓

	// counter += this.loadBeanDefinitions(location);
	@Override
	public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(location, null);
	}

下一步↓

  1. 获取 resourceLoader 对象
  2. 调用 DefaultResourceLoader的getResource完成具体的Resource定位
// return loadBeanDefinitions(location, null);
	public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
        ResourceLoader resourceLoader = this.getResourceLoader();
        if (resourceLoader == null) {
            throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
        } else {
            int loadCount;
            if (!(resourceLoader instanceof ResourcePatternResolver)) {
                Resource resource = resourceLoader.getResource(location);
                loadCount = this.loadBeanDefinitions((Resource)resource);
                if (actualResources != null) {
                    actualResources.add(resource);
                }

                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
                }

                return loadCount;
            } else {
                try {
                    Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
                    loadCount = this.loadBeanDefinitions(resources);
                    if (actualResources != null) {
                        Resource[] var6 = resources;
                        int var7 = resources.length;

                        for(int var8 = 0; var8 < var7; ++var8) {
                            Resource resource = var6[var8];
                            actualResources.add(resource);
                        }
                    }

                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
                    }

                    return loadCount;
                } catch (IOException var10) {
                    throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var10);
                }
            }
        }
    }

下一步↓

	@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;
	}

下一步↓

// class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader
@Override
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(new EncodedResource(resource));
	}

// (new EncodedResource(resource)); 编码设置:默认为空
    public EncodedResource(Resource resource) {
        this(resource, (String)null, (Charset)null);
    }
    private EncodedResource(Resource resource, String encoding, Charset charset) {
        Assert.notNull(resource, "Resource must not be null");
        this.resource = resource;
        this.encoding = encoding;
        this.charset = charset;
    }

下一步↓

  1. 通过属性记录已经加载的资源
  2. 从encoderResource中获取已经封装的Resource对象并再次从Resource中获取其中的inpoutStream
    • 读取到的配置对象是字符串或字节
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);
				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();
			}
		}
	}

1.3.2.1.6.4.1 doLoadBeanDefinitions

获取xml文件的document对象,解析过程由doucumentLoader完成

  • 从String[] - String - Resource[] - Resouce,最终将resource读取成一个document文档,将节点信息封装成一个个的BeanDefinitions对象
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			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);
		}
	}

1.3.2.1.6.4.1-1 doLoadBeanDefinitions

xml配置文件可能是dtd文件或xsd文件,会进行一个验证

	protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
		return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
				getValidationModeForResource(resource), isNamespaceAware());
	}

下一步↓

  1. 如果手动制定了验证模式,则使用指定的验证模式
  2. 如果没有指定验证模式,则使用自动检测
    protected int getValidationModeForResource(Resource resource) {
        int validationModeToUse = getValidationMode();
        if (validationModeToUse != VALIDATION_AUTO) {
            return validationModeToUse;
        }
        int detectedMode = detectValidationMode(resource);
        if (detectedMode != VALIDATION_AUTO) {
            return detectedMode;
        }
        // Hmm, we didn't get a clear indication... Let's assume XSD,
        // since apparently no DTD declaration has been found up until
        // detection stopped (before finding the document's root tag).
        return VALIDATION_XSD;
    }

下一步↓
再深入就不贴代码了。
接下来,会检测配置文件是dtd还是xsd格式,然后进行一个文件的校验操作(0手动、1自动、2DTD、3XSD)。
之后,将文件解析出来,封装成一个Document对象(包含了node节点信息)

1.3.2.1.6.4.1-2 registerBeanDefinitions

对xml的beanDefinition进行解析

	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;
	}

下一步↓

	protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
		return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));

    public int getBeanDefinitionCount() {
		return this.beanDefinitionMap.size();
	}
// 一个上下文对象
	public XmlReaderContext createReaderContext(Resource resource) {
		return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
				this.sourceExtractor, this, getNamespaceHandlerResolver());
	}

// readerContext 获取到上下文
// 获取到根节点
	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
		Element root = doc.getDocumentElement();
		doRegisterBeanDefinitions(root);
	}

下一步↓

  1. delegate:解析器:处理标签里面的信息,进行解析工作
  2. preProcessXml、postProcessXml 默认空,可进行扩展实现
  3. parseBeanDefinitions:利用解析器解析bean
// class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader
	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);

		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;
				}
			}
		}

		preProcessXml(root);
		parseBeanDefinitions(root, this.delegate);
		postProcessXml(root);

		this.delegate = parent;
	}

下一步↓
对当前标签进行解析工作

	// class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
	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);
        }
    }

下一步↓
如何解析取决于写好的bean标签是默认命名空间的还是自定义的

	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);
		}
	}

  • 或者
    1. 获取对应的命名空间
    2. 更具命名空间找到对应的namespaceHandler
    3. 调用自定义的NameSpabeHandler进行解析
	public BeanDefinition parseCustomElement(Element ele) {
		return parseCustomElement(ele, null);
	}

	public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
		String namespaceUri = getNamespaceURI(ele);
		NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
		if (handler == null) {
			error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
			return null;
		}
		return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
	}

下一步↓

  • beanDefinitionHodler是beanDefinition对象的封装类,封装了BeanDefinition、bean的名字和别名,用它完成向IOC容器的注册
  • 解析得到beanDefinitionHolder 可以说 通过 beanDefinitionParserDelegate这个解析类对xml元素的信息按照spring的bean规则进行解析得到了 beanDefinition
  1. 通过解析类解析得到 beanDefinitionHolder
  2. 向IOC注册 beanDefinition
  3. 注册完成后发送消息
	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));
		}
	}
  1. 解析操作
    1. 解析id属性、解析name属性、如果由别名就将别名分割解析
    2. 对bean属性进行详细解析
      1. 判断class属性
      2. 解析parent属性
      3. 实例化操作、创建BeanDefinition对象
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    	return parseBeanDefinitionElement(ele, null);
    }

	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;
	}

	// 详细解析
	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);
			}
            // 创建装载bean信息的AbstractBeanDefinition对象,实际对象是GenericBeanDefinition
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);

			// 解析bean标签的其它各种属性
            parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            // 设置description信息
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

            // 解析元数据
			parseMetaElements(ele, bd);
            // 解析 lookup-method 属性
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            // 解析 replace-method 属性
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

			// 解析构造参数
            parseConstructorArgElements(ele, bd);
            // 解析property子元素
			parsePropertyElements(ele, bd);
            // 解析qualifier子元素
			parseQualifierElements(ele, bd);

			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;
	}
	// class BeanDefinitionParserDelegate
	protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
			throws ClassNotFoundException {

		return BeanDefinitionReaderUtils.createBeanDefinition(
				parentName, className, this.readerContext.getBeanClassLoader());
	}

// class BeanDefinitionReaderUtils
	public static AbstractBeanDefinition createBeanDefinition(
			String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {

		GenericBeanDefinition bd = new GenericBeanDefinition();
		bd.setParentName(parentName);
		if (className != null) {
			if (classLoader != null) {
				bd.setBeanClass(ClassUtils.forName(className, classLoader));
			}
			else {
				bd.setBeanClassName(className);
			}
		}
		return bd;
	}
  1. 向IOC容器注册 beanDefinition
    public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		// 使用beanName做唯一标识注册
        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);
			}
		}
	}
//class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
	@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 {
                // 注册前的最后校验,不同于之前的xml文件校验,主要是对AbstractBeanDefinition属性的methodOverrides校验
                // 校验methodOverrides 是否于工厂方法并存或者 methodOverrides对应方法不存在
				((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);
        // 处理已经注册的beanName情况
		if (oldBeanDefinition != null) {
            // 如果对应的beanName已经注册且配置了bean不允许被覆盖:抛出异常
			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 + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
            // 判断bean有没有被启动
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
						updatedSingletons.remove(beanName);
						this.manualSingletonNames = updatedSingletons;
					}
				}
			}
			else {
                // 注册beanDefinition
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
                // 记录beanName
				this.beanDefinitionNames.add(beanName);
				this.manualSingletonNames.remove(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (oldBeanDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}
// class SimpleAliasRegistry implements AliasRegistry
	public void registerAlias(String name, String alias) {
        Assert.hasText(name, "'name' must not be empty");
        Assert.hasText(alias, "'alias' must not be empty");
        if (alias.equals(name)) {
            this.aliasMap.remove(alias);
        } else {
            String registeredName = (String)this.aliasMap.get(alias);
            if (registeredName != null) {
                if (registeredName.equals(name)) {
                    return;
                }

                if (!this.allowAliasOverriding()) {
                    throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'.");
                }
            }

            this.checkForAliasCircle(name, alias);
            this.aliasMap.put(alias, name);
        }

    }

1.3.3 prepareBeanFactory 方法

对beanFactory 各种属性的填充
beanFactory 的类是 DefaultListableBeanFactory
image.png

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
        if (beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        if (!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if (!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if (!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
        }

    }

1.3.4 postProcessBeanFactory 方法

具体逻辑由子类实现,做额外的处理

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }

1.3.5 invokeBeanFactoryPostProcessors

调用beanFactory的各种处理器,自由扩展

  1. 获取所有合适的 BeanFactoryPostProcessor:首先,Spring 容器会通过各种途径(如配置文件、注解扫描等)收集所有符合条件的 BeanFactoryPostProcessor 实现类,包括一些内建的后置处理器和用户自定义的后置处理器。
  2. 执行 BeanFactoryPostProcessor:接下来,将获取到的 BeanFactoryPostProcessor 实例逐个执行。这通常涉及调用后置处理器的 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法,传入当前的 BeanFactory 对象作为参数。
  3. 初始化 BeanFactoryPostProcessor:对于已执行的 BeanFactoryPostProcessor,容器可能会在此阶段执行一些初始化操作,确保它们处于可用状态。
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

    }

//  PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
 public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet();
        int var9;
        ArrayList priorityOrderedPostProcessors;
        ArrayList orderedPostProcessors;
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
            List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new LinkedList();
            Iterator var6 = beanFactoryPostProcessors.iterator();

            while(var6.hasNext()) {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryPostProcessors.add(registryPostProcessor);
                } else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            priorityOrderedPostProcessors = new ArrayList();
            String[] var22 = postProcessorNames;
            var9 = postProcessorNames.length;

            int var10;
            for(var10 = 0; var10 < var9; ++var10) {
                String ppName = var22[var10];
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
            registryPostProcessors.addAll(priorityOrderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            orderedPostProcessors = new ArrayList();
            String[] var26 = postProcessorNames;
            var10 = postProcessorNames.length;

            int var30;
            for(var30 = 0; var30 < var10; ++var30) {
                String ppName = var26[var30];
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            sortPostProcessors(beanFactory, orderedPostProcessors);
            registryPostProcessors.addAll(orderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
            boolean reiterate = true;

            while(reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                String[] var28 = postProcessorNames;
                var30 = postProcessorNames.length;

                for(int var33 = 0; var33 < var30; ++var33) {
                    String ppName = var28[var33];
                    if (!processedBeans.contains(ppName)) {
                        BeanDefinitionRegistryPostProcessor pp = (BeanDefinitionRegistryPostProcessor)beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                        registryPostProcessors.add(pp);
                        processedBeans.add(ppName);
                        pp.postProcessBeanDefinitionRegistry(registry);
                        reiterate = true;
                    }
                }
            }

            invokeBeanFactoryPostProcessors((Collection)registryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
            invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        } else {
            invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        }

        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<String> orderedPostProcessorNames = new ArrayList();
        List<String> nonOrderedPostProcessorNames = new ArrayList();
        String[] var21 = postProcessorNames;
        int var24 = postProcessorNames.length;

        String ppName;
        for(var9 = 0; var9 < var24; ++var9) {
            ppName = var21[var9];
            if (!processedBeans.contains(ppName)) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                } else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
        }

        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        priorityOrderedPostProcessors = new ArrayList();
        Iterator var25 = orderedPostProcessorNames.iterator();

        while(var25.hasNext()) {
            String postProcessorName = (String)var25.next();
            priorityOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }

        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        orderedPostProcessors = new ArrayList();
        Iterator var32 = nonOrderedPostProcessorNames.iterator();

        while(var32.hasNext()) {
            ppName = (String)var32.next();
            orderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }

        invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        beanFactory.clearMetadataCache();
    }

1.3.6 registerBeanPostProcessors 方法

解析和注册所有的BeanPostProcessor

    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

	// PostProcessorRegistrationDelegate.registerBeanPostProcessors
	public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList();
        List<String> orderedPostProcessorNames = new ArrayList();
        List<String> nonOrderedPostProcessorNames = new ArrayList();
        String[] var8 = postProcessorNames;
        int var9 = postProcessorNames.length;

        String ppName;
        BeanPostProcessor pp;
        for(int var10 = 0; var10 < var9; ++var10) {
            ppName = var8[var10];
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                pp = (BeanPostProcessor)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);
            }
        }

        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
        Iterator var14 = orderedPostProcessorNames.iterator();

        while(var14.hasNext()) {
            String ppName = (String)var14.next();
            BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        sortPostProcessors(beanFactory, orderedPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var17 = nonOrderedPostProcessorNames.iterator();

        while(var17.hasNext()) {
            ppName = (String)var17.next();
            pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
        sortPostProcessors(beanFactory, internalPostProcessors);
        registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

1.3.7 initMessageSource方法

**Spring国际化:**用于初始化消息源(MessageSource)的方法。消息源在 Spring 中用于提供国际化(i18n)和本地化(l10n)的支持,用于处理应用程序中的文本消息,例如错误信息、提示信息等,并根据用户的语言环境进行相应的转换。

protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("messageSource")) {
            this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource)this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    hms.setParentMessageSource(this.getInternalParentMessageSource());
                }
            }

            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Using MessageSource [" + this.messageSource + "]");
            }
        } else {
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(this.getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton("messageSource", this.messageSource);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate MessageSource with name 'messageSource': using default [" + this.messageSource + "]");
            }
        }

    }

1.3.8 initApplicationEventMulticaster 方法

初始化事件监听器

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
            this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]");
            }
        }

    }

1.3.9 onRefresh 方法

    protected void onRefresh() throws BeansException {
    }

1.3.10 registerListeners 方法

注册监听器

protected void registerListeners() {
        Iterator var1 = this.getApplicationListeners().iterator();

        while(var1.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var1.next();
            this.getApplicationEventMulticaster().addApplicationListener(listener);
        }

        String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
        String[] var7 = listenerBeanNames;
        int var3 = listenerBeanNames.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            String listenerBeanName = var7[var4];
            this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            Iterator var9 = earlyEventsToProcess.iterator();

            while(var9.hasNext()) {
                ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
                this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }

    }

1.3.11 finishBeanFactoryInitialization 方法

完成所有非懒加载的单例对象的实例化操作

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                public String resolveStringValue(String strVal) {
                    return AbstractApplicationContext.this.getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }

1.3.12 finishRefresh 方法

** 完成整个容器的启动,所有的对象都准备完成,可以进行后续业务流程的操作,清除上下文缓存,初始化生命周期处理器,发送刷新完成事件**

    protected void finishRefresh() {
        this.initLifecycleProcessor();
        this.getLifecycleProcessor().onRefresh();
        this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
        LiveBeansView.registerApplicationContext(this);
    }

1.3.13 resetCommonCaches 方法

    protected void resetCommonCaches() {
        ReflectionUtils.clearCache();
        ResolvableType.clearCache();
        CachedIntrospectionResults.clearClassLoader(this.getClassLoader());
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/156834.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【面试经典150 | 数学】回文数

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;反转一半数字 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本…

【网络安全】伪装IP网络攻击的识别方法

随着互联网的普及和数字化进程的加速&#xff0c;网络攻击事件屡见不鲜。其中&#xff0c;伪装IP的网络攻击是一种较为常见的攻击方式。为了保护网络安全&#xff0c;我们需要了解如何识别和防范这种攻击。 一、伪装IP网络攻击的概念 伪装IP网络攻击是指攻击者通过篡改、伪造I…

HTTPS加密为什么能保证网络安全?

随着互联网的普及和发展&#xff0c;网络安全问题日益严重。为了保护用户的隐私和数据安全&#xff0c;许多网站都采用了HTTPS加密技术。那么&#xff0c;HTTPS加密为什么可以保证网络安全呢&#xff1f; 原因是HTTP协议采用的是数据明文传输方式。用户从客户端浏览器提交数据…

怎样能写好年终总结报告?

年终总结报告是每个企业、部门、团队都必须完成的一项任务。它是对一年来工作的回顾和总结&#xff0c;也是对下一年工作的规划和展望。写好年终总结报告&#xff0c;不仅可以反映出一个人的工作能力和水平&#xff0c;也可以为下一年的工作提供依据和指导。那么&#xff0c;怎…

产品经理的能力模型是什么?

一个产品的成功需要团队成员利用自己的技能共同合作完成。作为团队的核心和产品的主导者&#xff0c;产品经理需要具备一定的能力模型&#xff0c;以更好地完成工作。下面从五个方面进行解答。 首先&#xff0c;产品经理需要具备需求分析的能力。需求是用户在特定场景下产生的欲…

SystemVerilog学习 (10)——线程控制

一、概述 在实际硬件中,时序逻辑通过时钟沿来激活,组合逻辑的输出则随着输人的变化而变化。所有这些并发的活动在Verilog 的寄存器传输级上是通过initial和 always块语句、实例化和连续赋值语句来模拟的。为了模拟和检验这些语句块,测试平台使用许多并发执行的线程。在测试平台…

数据仓库-数仓架构

1 数据仓库建设方法论 1.1 项目背景 数据仓库将建设成为融通全公司数据资产&#xff0c;提供便捷数据分析和数据服务&#xff0c;支持全公司数字化经营与创新。 1.2 数据仓库概述 数据仓库是一个面向主题的、集成的、相对稳定的、反映有历史变化的数据集合&#xff0c;用于…

盘点十大免费低/无代码开发软件,数字化转型看这里

在数字化日益普及的当下&#xff0c;低代码开发技术逐渐受到大众的追捧。这种技术让缺乏编程经验的大众也能轻松创建应用程序和网站。通过直观的图形界面和拖拽功能&#xff0c;用户可以无需编写任何代码&#xff0c;轻松实现自己的开发需求。本文将为您介绍十大免费的低代码开…

Kubernetes Dashboard部署ImagePullBackOff问题处理

通常&#xff0c;出现ImagePullBackOff问题是由于Kubernetes集群无法拉取所需的镜像导致的。解决这个问题的方法通常包括以下步骤&#xff1a; 1. 检查Pod的描述信息&#xff1a; kubectl describe pod/[pod名称] --namespacekubernetes-dashboard 查看Events部分是否有关于…

再推新品,但华为智慧屏还在等一个契机

文 | 智能相对论 作者 | 佘凯文 在智能电动汽车狂潮下&#xff0c;昔日热闹的“智能电视”类市场&#xff08;包括“智慧屏”、“智能屏”、“智慧电视”、“社交电视”等等五花八门的产品&#xff09;愈发冷清——近些年来&#xff0c;家电行业内部呈现出的“分化”越发明显…

PatchMatchNet笔记

PatchMatchNet笔记 1 概述2 PatchmatchNet网络结构图2.1 多尺度特征提取2.2 基于学习的补丁匹配 3 性能评价 PatchmatchNet: Learned Multi-View Patchmatch Stereo&#xff1a;基于学习的多视角补丁匹配立体算法 1 概述 特点   高速&#xff0c;低内存&#xff0c;可以处理…

OpenLayer系列——【一】初识OpenLayer与OpenLayer视图操作

初识OpenLayer 1、初始化地图渲染 安装openlayer依赖 npm i ol首先准备一个容器用来渲染地图 <div id"map" ref"map" style"width: 100%; height: 100%" />导入依赖初始化地图 import ol/ol.css; import OSM from ol/source/OSM.js; …

最新AI创作系统ChatGPT系统运营源码+支持GPT-4多模态模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

浅谈智能安全配电装置应用在银行配电系统中

【摘要】银行是国家重点安全保护部分&#xff0c;关系到社会资金的稳定&#xff0c;也是消防重点单位。消防安全是银行工作的重要组成部分。在银行配电系统中应用智能安全配电装置&#xff0c;可以提高银行的智能控制水平&#xff0c;有效预防电气火灾。 【关键词】银行&#…

Python 集成 Nacos 配置中心

Python 集成 Nacos 配置中心 下载 Nacos 官方 pyhton 库 pip install nacos-sdk-python # 指定国内阿里云镜像源 pip3 install nacos-sdk-python -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com配置 Nacos 相关信息 Global:nacos:port: 8848…

高阶数据结构---树状数组

文章目录 楼兰图腾一个简单的整数问题 一个简单的整数问题2谜一样的牛 一、楼兰图腾OJ链接 二、一个简单的整数问题OJ链接 三、一个简单的整数问题2OJ链接 四、谜一样的牛OJ链接

Redis篇---第四篇

系列文章目录 文章目录 系列文章目录前言一、说一下 Redis 有什么优点和缺点二、Redis 缓存刷新策略有哪些?三、Redis 持久化方式有哪些?以及有什么区别?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章…

文件包含_具体场景、zip、php相关问题

具体场景—上传可控的文件 具体场景—远程文件包含 具体场景—伪协议

编译和链接

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 1. 翻译环境和运行环境 2. 翻译环境 2.1 预处理&#xff08;预编译&#xff09; 2.2 编译 2.2.1 词法分析&#xff1a; 2.2.2 语法分析 2.2.3 语义分析 2.3 汇编 2…

开发知识点-Git

团队协作-Git Giteegitee 创建仓库打开项目所在目录&#xff0c;右键选择Git Bush Here(你要确定电脑上已经安装了Git&#xff09;初始化本地仓库配置验证信息。 完美解决github访问速度慢介绍Git 与 SVN 区别IDEA 添加 gitee Gitee Git Gitee 大家都知道国内访问 Github 速度…