Spring源码—初识IOC

news2024/11/27 2:22:55

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

水库大坝安全监测预警系统的重要作用

水库大坝建造在地质构造复杂、岩土特性不均匀的地基上&#xff0c;在各种荷载的作用和自然因素的影响下&#xff0c;其工作性态和安全状况随时都在变化。如果出现异常&#xff0c;又不被及时发现&#xff0c;其后果不堪设想。全天候实时监测&#xff0c;实时掌握水库水位、雨情…

基于JuiceFS 的低成本 Elasticsearch 云上备份存储

杭州火石创造是国内专注于产业大数据的数据智能服务商&#xff0c;为了解决数据存储及高效服务客户需求&#xff0c;选择了 Elasticsearch 搜索引擎进行云上存储。基于性能和成本的考虑&#xff0c;在阿里云选择用本地 SSD ECS 机型自建集群。但由于是自建集群&#xff0c;如何…

uniapp Android如何打开常用系统设置页面?

uniapp Android 如何打开常用系统设置页面&#xff1f; 在使用App过程时&#xff0c;有时候会对一些权限获取&#xff0c;比如打开蓝牙、打开通知栏通知等设置&#xff0c;我们如何快速跳转到需要的设置页面&#xff1f; 文章目录 uniapp Android 如何打开常用系统设置页面&…

μC/OS-II---消息队列管理2(os_q.c)

目录 消息队列的主要优点消息队列和消息邮箱消息队列相关操作向消息队列发送消息(FIFO)向消息队列发送消息(LIFO)向消息队列发送消息(扩展&#xff09;消息队列获取/无等待清空消息队列消息队列信息获取消息队列中断等待 消息队列的主要优点 消息队列的主要优点是解耦和异步通…

rocketmq5.X 单机搭建 虚拟机搭建rocketmq5.1.4 搭建最新版本mq rocketmq5.1.4版本单体搭建 rocketmq(一)

1. 官网下载地址&#xff1a; 下载 | RocketMQ 2. 配置环境&#xff1a; 我是在/etc/profile.d 新建了一个rocketmq_env.sh 配置了jdk, maven, 以及mq. mq文件下载的 配置完之后&#xff0c;刷新环境source /etc/profile 3. 配置rocket mq 的jvm配置&#xff0c;就是两个启…

Docker Compose详细教程(从入门到放弃)

对于现代应用来说&#xff0c;大多都是通过很多的微服务互相协同组成的一个完整应用。例如&#xff0c; 订单管理、用户管理、品类管理、缓存服务、数据库服务等&#xff0c;它们构成了一个电商平台的应 用。而部署和管理大量的服务容器是一件非常繁琐的事情。而 Docker Compos…

基于安卓android微信小程序的装修家装小程序

项目介绍 巧匠家装小程序的设计主要是对系统所要实现的功能进行详细考虑&#xff0c;确定所要实现的功能后进行界面的设计&#xff0c;在这中间还要考虑如何可以更好的将功能及页面进行很好的结合&#xff0c;方便用户可以很容易明了的找到自己所需要的信息&#xff0c;还有系…

PLC电力载波通讯,一种新的IoT通讯技术

前言: PLC-IoT 是 PLC 技术应用在物联场景的创新实践,有效解决电力线路信号干扰、衰减问题,支持 IP 化通信能力,使能终端设备智能化,构建智慧边缘联接。PLC让传统IoT有了更多的连接可能: 电力线通信技术适用的场景包括电力配用电网络、城市智慧路灯、交通路口信号灯、园…

Python代码运行速度提升技巧!Python远比你想象中的快~

文章目录 前言一、使用内置函数二、字符串连接 VS join()三、创建列表和字典的方式四、使用 f-Strings五、使用Comprehensions六、附录- Python中的内置函数总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项…

基于SSM的药店药品销售系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

IDEA导入jar包

通过maven导入本地包 mvn install:install-file -DfileD:\WebProject\ERP\zhixing-heyue-erp-server\zxhy-service-api\src\main\java\com\zxhy\service\api\invoice\baiwang\lib\com_baiwang_bop_sdk_outer_3_4_393.jar -DgroupIdcom.baiwang -DartifactIdbaiwang.open -Dver…

C语言每日一题(29)合并两个有序链表

力扣网 21合并两个有序链表 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 思路分析 最基本的一种思路就是&#xff0c;遍历两个链表&#xff0c;将对应结点的值进行比较&#xff0c;题目要求是要升序排…

错误:ERROR:torch.distributed.elastic.multiprocessing.api:failed

在多卡运行时&#xff0c;会出现错误&#xff08;ERROR:torch.distributed.elastic.multiprocessing.api:failed&#xff09;&#xff0c;但是单卡运行并不会报错&#xff0c;通常在反向梯度传播时多卡梯度不同步。但我是在多卡处理数据进行tokenizer阶段报错&#xff0c;这竟然…

ZYNQ实验--Petalinux 安装

一、Petalinux 简介 PetaLinux是一个由Xilinx公司提供的嵌入式Linux开发工具套件&#xff0c;专门用于在Xilinx器件上构建、定制和部署嵌入式Linux系统。这个工具套件旨在简化嵌入式系统的开发过程&#xff0c;特别是针对使用Xilinx的可编程逻辑器件的系统。PetaLinux是Xilinx …

基于SpringBoot的教务管理系统

基于SpringBoot的教务管理系统 教务管理系统开发技术功能模块代码结构运行截图数据库源码获取 教务管理系统 欢迎访问此博客&#xff0c;是否为自己的毕业设计而担忧呢&#xff1f;是否感觉自己的时间不够做毕业设计呢&#xff1f;那你不妨看一下下面的文章&#xff01; 开发…

基于单片机无人售货机仿真及源程序

一、系统方案 1、本设计采用51单片机作为主控器。 2、商品选择&#xff0c;购买数量选择&#xff0c;投币&#xff0c;液晶1602显示。 3、电机模拟出货。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 void lcd_1602_init() //LCD1602初始…

实用干货丨Eolink Apikit 配置和告警规则的各种用法

API在运行过程中可能会遇到各种异常情况&#xff0c;如响应时间过长、调用频率过高、请求参数错误等&#xff0c;这些异常会对系统的稳定性和性能产生严重影响。因此&#xff0c;对API进行异常监控和告警是非常必要的。本文将介绍 Eolink Apikit 中使用的告警规则&#xff0c;帮…

UWA Pipeline 2.5.1 版本更新说明

UWA Pipeline是一款面向游戏开发团队的本地协作平台&#xff0c;旨在为游戏开发团队搭建专属的DevOps研发交付流水线&#xff0c;提供可视化的CICD操作界面、高可用的自动化测试以及UWA性能保障服务的无缝贴合等实用功能。 近期UWA Pipeline迎来2.5.1版本更新&#xff0c;进一…

【小黑送书—第六期】>>AI时代,程序员如何应对挑战——《AI时代系列书籍》

在AI时代&#xff0c;程序员面临着新的机遇和挑战。为了适应这个快速发展的时代&#xff0c;掌握新技能并采取相应的应对策略是至关重要的。 对于办公人员或程序员来说&#xff0c;利用AI可以提高工作效率。例如&#xff0c;使用AI助手可以帮助自动化日常的重复性工作&#xff…

软件测试方案该怎么做?

做某项工作之前都需要有个计划或方案&#xff0c;软件测试亦如此。软件测试方案就是描述测试目的、范围、方法和软件测试的重点等文档。对于验证软件产品的可接受程度编写测试计划文档是一种有用的方式&#xff0c;可以使测试工作和整个开发工作融合起来&#xff0c;让资源和变…