zoukankan      html  css  js  c++  java
  • 源码分析-SpringFramework之IoC容器初始化

    原创文章,转发请标注https://www.cnblogs.com/boycelee/p/12595884.html

    分析例子

    启动类

    Application,使用的是ClassPathXmlApplicationContext来加载xml文件

    /**
     * @author jianw.li
     * @date 2020/3/16 11:53 PM
     * @Description: TODO
     */
    public class MyApplication {
        private static final String CONFIG_LOCATION = "classpath:application_context.xml";
    
        private static final String BEAN_NAME = "hello";
    
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext(CONFIG_LOCATION);
            Hello hello = (Hello) ac.getBean(BEAN_NAME);
            hello.sayHello();
        }
    }
    

    Bean

    /**
     * @author jianw.li
     * @date 2020/3/16 11:53 PM
     * @Description: TODO
     */
    public class Hello {
    
    	public void sayHello() {
    		System.out.println("Hello World");
    	}
    }
    

    配置文件

    ​ 在resources下建立名为classpath:application_context.xml的配置文件,并配置好Bean

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    	<bean id="hello" class="com.boyce.bean.Hello"></bean>
    
    </beans>
    

    总体结构

    ClassPathXmlApplicationContext继承体系如下:

    KWJf7l

    IoC总体结构图如下:

    image-20200322155805716

    源码分析

    BeanFactory获取

    ClassPathXmlApplicationContext

    //构造函数,创建ClassPathXmlApplicationContext,其中configLocation为Bean所在的文件路径
    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    		this(new String[] {configLocation}, true, null);
    }
    
    public ClassPathXmlApplicationContext(
    			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
    			throws BeansException {
        //null
    		super(parent);
        //设置配置路径至ApplicationContext中
    		setConfigLocations(configLocations);
    		if (refresh) {
          //核心方法,refresh会将旧的ApplicaionContext销毁
    			refresh();
    		}
    	}
    
    

    AbstractApplicationContext

    refresh

    ​ 核心方法,refresh销毁旧ApplicationContext,生成新的ApplicationContext

    @Override
    	public void refresh() throws BeansException, IllegalStateException {
    		//加锁.没有明确对象,只是想让一段代码同步,可以创建Object startupShutdownMonitor = new Object()
    		synchronized (this.startupShutdownMonitor) {
    			// 为context刷新准备.设置启动时间,设置激活状态等
    			prepareRefresh();
    
    			// 告知子类刷新内部bean factory.
          // 获取BeanFactory,默认实现DefaultListableBeanFactory
          // 加载BeanDefinition,并注册至BeanDefinitionRegistry
          // (核心)
    			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
    			// Prepare the bean factory for use in this context.
          // 进行BeanFactory的预准备工作,对BeanFactory进行信息设置
    			prepareBeanFactory(beanFactory);
    
    			try {
    				// Allows post-processing of the bean factory in context subclasses.
            // BeanFactory准备工作
    				postProcessBeanFactory(beanFactory);
    
    				// Invoke factory processors registered as beans in the context.
            // 实例化实现BeanFactoryPostProcessor接口的Bean,并调用接口方法
    				invokeBeanFactoryPostProcessors(beanFactory);
    
    				// Register bean processors that intercept bean creation.
            // 注册BeanPostProcessors(Bean的后置处理器),创建Bean的前后等执行
    				registerBeanPostProcessors(beanFactory);
    
    				// Initialize message source for this context.
            // 初始化MessageSource组件,国际化相关功能
    				initMessageSource();
    
    				// Initialize event multicaster for this context.
            // 初始化事件派发器
    				initApplicationEventMulticaster();
    
    				// Initialize other special beans in specific context subclasses.
            // 子类重写,在容器刷新时可以自定义逻辑;如创建Tomcat、Jetty等Web服务器
    				onRefresh();
    
    				// Check for listener beans and register them.
            // 注册应用的监听器(注册实现ApplicationListener接口的监听器bean)
    				registerListeners();
    
    				// Instantiate all remaining (non-lazy-init) singletons.
    				// 初始化所有非懒加载单例bean
            // 属性填充
            // 初始化方法的调用(例如afterPropertiesSet、init-method方法)
            // 调用BeanPostProcessor(后置处理器)对实例bean进行后置处理
            // (核心)
    				finishBeanFactoryInitialization(beanFactory);
    
    				// Last step: publish corresponding event.
    				//广播初始化完成
    				finishRefresh();
    			}
    
    			catch (BeansException ex) {
    				if (logger.isWarnEnabled()) {
    					logger.warn("Exception encountered during context initialization - " +
    							"cancelling refresh attempt: " + ex);
    				}
    
    				// Destroy already created singletons to avoid dangling resources.
    				destroyBeans();
    
    				// Reset 'active' flag.
    				cancelRefresh(ex);
    
    				// Propagate exception to caller.
    				throw ex;
    			}
    
    			finally {
    				// Reset common introspection caches in Spring's core, since we
    				// might not ever need metadata for singleton beans anymore...
    				resetCommonCaches();
    			}
    		}
    	}
    
    obtainFreshBeanFactory

    ​ 告知子类刷新内部bean factory.

    ​ 核心方法,初始化BeanFactory、加载Bean、注册Bean

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    		//刷新Bean工厂,关闭并销毁旧BeanFacroty
    		refreshBeanFactory();
    		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    		if (logger.isDebugEnabled()) {
    			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    		}
    		return beanFactory;
    	}
    
    refreshBeanFactory

    ​ 关闭并销毁旧BeanFactory,创建与初始化新BeanFactory。为什么是DefaultListableBeanFactory?

    @Override
    	protected final void refreshBeanFactory() throws BeansException {
        // 判断是否已有BeanFactory
    		if (hasBeanFactory()) {
          // 如果已有,则销毁beans且关闭BeanFactory
    			destroyBeans();
    			closeBeanFactory();
    		}
    		try {
    			//初始化DefaultListableBeanFactory,为什么选择实例化DefaultListableBeanFactory?而不是其他的Bean工厂
    			DefaultListableBeanFactory beanFactory = createBeanFactory();
    			//Bean工厂序列化设置id
    			beanFactory.setSerializationId(getId());
    			//定制Bean工厂,设置不允许覆盖Bean,不允许循环依赖等
    			customizeBeanFactory(beanFactory);
    			//加载BeanDefinitions
    			loadBeanDefinitions(beanFactory);
    			//此处synchronized块与#hasBeanFactory中的synchronized块存在关联,此处锁住之后hasBeanFactory中的synchronized块将等待
    			//避免beanFactory未销毁或未关闭的情况
    			synchronized (this.beanFactoryMonitor) {
    				this.beanFactory = beanFactory;
    			}
    		}
    		catch (IOException ex) {
    			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    		}
    	}
    
    customizeBeanFactory

    ​ 定制BeanFactory。设置Bean覆盖、循环依赖等。什么是循环依赖?

    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    		if (this.allowBeanDefinitionOverriding != null) {
    			//默认值为false不允许对Bean进行覆盖
    			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    		}
    		if (this.allowCircularReferences != null) {
    			//默认值为false,不允许循环依赖
    			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
    		}
    	}
    

    BeanFactory获取时序图

    BeanFactory3

    BeanDefinition加载注册

    AbstractXmlApplicationContext

    loadBeanDefinitions
    @Override
    	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
        // 为BeanFactory创建XmlBeanDefinitionReader对象,用于解析xml对象
    		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    
    		// Configure the bean definition reader with this context's
    		// resource loading environment.
        // 为beanDefinitionReader设置环境信息
    		beanDefinitionReader.setEnvironment(this.getEnvironment());
    		beanDefinitionReader.setResourceLoader(this);
    		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    
    		// Allow a subclass to provide custom initialization of the reader,
    		// then proceed with actually loading the bean definitions.
        // 允许子类自定义初始化阅读器
    		initBeanDefinitionReader(beanDefinitionReader);
        //加载BeanDefinition
    		loadBeanDefinitions(beanDefinitionReader);
    	}
    
    loadBeanDefinitions
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    		Resource[] configResources = getConfigResources();
    		if (configResources != null) {
    			//加载资源对象,最终还是会回到这种方式去加载bean.
    			reader.loadBeanDefinitions(configResources);
    		}
    		String[] configLocations = getConfigLocations();
    		if (configLocations != null) {
    			//加载资源路径吗
    			reader.loadBeanDefinitions(configLocations);
    		}
    	}
    

    AbstractBeanDefinitionReader

    loadBeanDefinitions
    @Override
    	public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    		Assert.notNull(locations, "Location array must not be null");
    		int counter = 0;
    		//循环配置文件路径
    		for (String location : locations) {
    			counter += loadBeanDefinitions(location);
    		}
    		return counter;
    	}
    
    public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
    		ResourceLoader resourceLoader = getResourceLoader();
    		if (resourceLoader == null) {
    			throw new BeanDefinitionStoreException(
    					"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
    		}
    
    		if (resourceLoader instanceof ResourcePatternResolver) {
    			// Resource pattern matching available.
    			try {
            // 将xml转为Resource,所以上面的两种资源加载方式,最终都会回到Resource为参数的加载方式
    				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
            // 加载资源配置中的BeanDeinition对象,并返回数量
    				int loadCount = loadBeanDefinitions(resources);
    				if (actualResources != null) {
    					for (Resource resource : resources) {
    						actualResources.add(resource);
    					}
    				}
    				if (logger.isDebugEnabled()) {
    					logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
    				}
    				return loadCount;
    			}
    			catch (IOException ex) {
    				throw new BeanDefinitionStoreException(
    						"Could not resolve bean definition resource pattern [" + location + "]", ex);
    			}
    		}
    		else {
    			// Can only load single resources by absolute URL.
    			Resource resource = resourceLoader.getResource(location);
    			int loadCount = loadBeanDefinitions(resource);
    			if (actualResources != null) {
    				actualResources.add(resource);
    			}
    			if (logger.isDebugEnabled()) {
    				logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
    			}
    			return loadCount;
    		}
    	}
    
    @Override
    	public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
                // 就算是入参为location的loadBeanDefinitions,最终也会回到入参为resource的loadBeanDefinitions中
    		Assert.notNull(resources, "Resource array must not be null");
    		int counter = 0;
    		for (Resource resource : resources) {
    			counter += loadBeanDefinitions(resource);
    		}
    		return counter;
    	}
    

    XmlBeanDefinitionReader

    loadBeanDefinitions

    ​ 从详细的XML文件中加载Bean

    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());
    		}
    
    		//用于存储编译过的Reource
    		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    		if (currentResources == null) {
    			currentResources = new HashSet<>(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 {
            // 将xml文件流封装为InputSource对象
    				InputSource inputSource = new InputSource(inputStream);
    				if (encodedResource.getEncoding() != null) {
    					inputSource.setEncoding(encodedResource.getEncoding());
    				}
            // 执行加载BeanDefinitions
    				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();
    			}
    		}
    	}
    
    doLoadBeanDefinitions

    ​ 从xml文件中加载bean,将xml转为Document并注册Bean

    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    			throws BeanDefinitionStoreException {
    		try {
    			// 将xml转为Document
    			Document doc = doLoadDocument(inputSource, resource);
    			// 解析document对象,封装BeanDefinition对象并注册Bean
    			return registerBeanDefinitions(doc, resource);
    		}
    		...
    	}
    
    registerBeanDefinitions

    ​ 计算从当前配置文件中加载bean的数量

    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        // 获取已注册的BeanDefinition的数量
    		int countBefore = getRegistry().getBeanDefinitionCount();
        // 注册BeanDefinition
    		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        // 计算新注册BeanDefinition的数量并返回
    		return getRegistry().getBeanDefinitionCount() - countBefore;
    	}
    

    DefaultBeanDefinitionDocumentReader

    registerBeanDefinitions

    ​ 从“spring-beans” xsd中解析bean。什么是xsd?XML结构定义 ( XML Schemas Definition)

    @Override
    	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    		this.readerContext = readerContext;
    		logger.debug("Loading bean definitions");
    		Element root = doc.getDocumentElement();
        // 执行注册BeanDefinitions
    		doRegisterBeanDefinitions(root);
    	}
    
    doRegisterBeanDefinitions

    ​ 从根节点开始注册每一个Bean

    /**
    	 * Register each bean definition within the given root {@code <beans/>} element.
    	 * 从根节点开始注册每一个Bean
    	 */
    	protected void doRegisterBeanDefinitions(Element root) {
    		// Any nested <beans> elements will cause recursion in this method. In
    		// order to propagate and preserve <beans> default-* attributes correctly,
    		// keep track of the current (parent) delegate, which may be null. Create
    		// the new (child) delegate with a reference to the parent for fallback purposes,
    		// then ultimately reset this.delegate back to its original (parent) reference.
    		// this behavior emulates a stack of delegates without actually necessitating one.
    		//可以通过spring.profiles.active设定当前环境激活的profile,例如配置prod,可以通过@ActiveProfiles配置
    
    		// 解析bean定义
        // 委托模式
    		BeanDefinitionParserDelegate parent = this.delegate;
    		this.delegate = createDelegate(getReaderContext(), root, parent);
    
    		if (this.delegate.isDefaultNamespace(root)) {
    			//获取元素中profile属性,可以通过xml或@Profile设置当前bean所属的profile
    			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
    			//不能做profile属性则直接跳过
    			if (StringUtils.hasText(profileSpec)) {
    				//配置多profile
    				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
    						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
    				//元素中的profile是否是环境指定的profiles之一
    				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
    					if (logger.isInfoEnabled()) {
    						logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
    								"] not matching: " + getReaderContext().getResource());
    					}
    					//不在当前环境指定的profile中则return
    					return;
    				}
    			}
    		}
    
    		preProcessXml(root);
        // 解析元素
    		parseBeanDefinitions(root, this.delegate);
    		postProcessXml(root);
    
    		this.delegate = parent;
    	}
    
    parseBeanDefinitions

    ​ 从文档根节点开始解析元素,import、alias、bean等

    /**
    	 * Parse the elements at the root level in the document:
    	 * "import", "alias", "bean".
    	 * @param root the DOM root element of the document
    	 */
    	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    		if (delegate.isDefaultNamespace(root)) {
    			NodeList nl = root.getChildNodes();
    			for (int i = 0; i < nl.getLength(); i++) {
    				Node node = nl.item(i);
    				if (node instanceof Element) {
    					Element ele = (Element) node;
    					if (delegate.isDefaultNamespace(ele)) {
    						//解析default namespace下的元素(例如:<import>、<alias>、<beans>、<bean>)
    						parseDefaultElement(ele, delegate);
    					}
    					else {
    						//解析Custom元素(例如:<mvc>、<context>、<aop>),自定义标签
    						delegate.parseCustomElement(ele);
    					}
    				}
    			}
    		}
    		else {
    			delegate.parseCustomElement(root);
    		}
    	}
    
    parseDefaultElement

    ​ 解析default namespace下的元素(例如:

    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)) {
    			//解析bean元素为BeanDefinition
    			processBeanDefinition(ele, delegate);
    		}
    		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
    			// recurse
    			doRegisterBeanDefinitions(ele);
    		}
    	}
    
    processBeanDefinition

    ​ 获取bean元素解析并注册

    /**
    	 * Process the given bean element, parsing the bean definition
    	 * and registering it with the registry.
    	 * 获取bean元素解析并注册
    	 */
    	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    		//解析bean元素成BeanDefinition,并将BeanDefinition封装成BeanDefinitionHolder对象
    		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    		if (bdHolder != null) {
    			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
    			try {
    				// Register the final decorated instance.
    				//注册装饰的实例,完成BeanDefinition注册
    				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
    			}
    			catch (BeanDefinitionStoreException ex) {
    				getReaderContext().error("Failed to register bean definition with name '" +
    						bdHolder.getBeanName() + "'", ele, ex);
    			}
    			// Send registration event.
    			//发送注册事件
    			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    		}
    

    BeanDefinitionReaderUtils

    registerBeanDefinition
    public static void registerBeanDefinition(
    			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    			throws BeanDefinitionStoreException {
    
    		// Register bean definition under primary name.
    		String beanName = definitionHolder.getBeanName();
    		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    
    		// Register aliases for bean name, if any.
    		String[] aliases = definitionHolder.getAliases();
    		if (aliases != null) {
    			for (String alias : aliases) {
    				registry.registerAlias(beanName, alias);
    			}
    		}
    	}
    

    DefaultListableBeanFactory

    registerBeanDefinition
    @Override
    	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    			throws BeanDefinitionStoreException {
    
    		Assert.hasText(beanName, "Bean name must not be empty");
    		Assert.notNull(beanDefinition, "BeanDefinition must not be null");
    
    		if (beanDefinition instanceof AbstractBeanDefinition) {
    			try {
    				((AbstractBeanDefinition) beanDefinition).validate();
    			}
    			catch (BeanDefinitionValidationException ex) {
    				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    						"Validation of bean definition failed", ex);
    			}
    		}
    
    		BeanDefinition oldBeanDefinition;
    		//beanDefinitionMap放置所有注册的Bean
    		oldBeanDefinition = this.beanDefinitionMap.get(beanName);
    
    		//如果bean名已存在
    		if (oldBeanDefinition != null) {
    			//不允许覆盖bean
    			if (!isAllowBeanDefinitionOverriding()) {
    				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    						"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
    						"': There is already [" + oldBeanDefinition + "] bound.");
    			}
    			//通过比较BeanRole.判断谁覆盖谁
    			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 + "]");
    				}
    			}
    			//新bean覆盖旧bean
    			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 + "]");
    				}
    			}
    			//将bean放置beanDefinitionMap中
    			this.beanDefinitionMap.put(beanName, beanDefinition);
    		}
    		//beanName没有与beanDefinitionMap中的重复
    		else {
    			//非正常情况下,其他的Bean已经初始化,如果已经有bean初始化,则使用者已经在进行业务操作,无法保证对beanDefinitionMap、beanDefinitionNames、manualSingletonNames进行操作的一些列动作的线程安全,所以需要加锁。参考:https://blog.csdn.net/qq_41907991/article/details/97614337
    			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<>(this.beanDefinitionNames.size() + 1);
    					updatedDefinitions.addAll(this.beanDefinitionNames);
    					updatedDefinitions.add(beanName);
    					this.beanDefinitionNames = updatedDefinitions;
    					if (this.manualSingletonNames.contains(beanName)) {
    						Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
    						updatedSingletons.remove(beanName);
    						this.manualSingletonNames = updatedSingletons;
    					}
    				}
    			}
    			else {
    				// Still in startup registration phase
    				//bean放置beanDefinitionMap中
    				this.beanDefinitionMap.put(beanName, beanDefinition);
    				//记录bean名称
    				this.beanDefinitionNames.add(beanName);
    				//bean不需要手动注册
    				this.manualSingletonNames.remove(beanName);
    			}
    			this.frozenBeanDefinitionNames = null;
    		}
    
    		if (oldBeanDefinition != null || containsSingleton(beanName)) {
    			resetBeanDefinition(beanName);
    		}
    	}
    

    BeanDefinition加载注册流程图

    BeanFactory3

    总结

    ​ 至此已经完成了IoC容器的初始化。将xml文件中的bean元素解析为Bean,将Bean注册至注册中心,并发送注册事件。DefaultListableBeanFactory建立Bean配置信息,这些信息都存放在BeanDefinitionMap中,由IoC容器来维护。

    ​ 最后,懂得不多,做得很少。文章肯定又不少错误,如大家发现麻烦及时指出,为了避免误导更多人,我也会及时学习并修改!

    引用参考

    [1]《Spring技术内幕》

    [2]https://www.javadoop.com/post/spring-ioc

    [3]https://github.com/seaswalker/spring-analysis/blob/master/note/Spring.md#classpathxmlapplicationcontext

  • 相关阅读:
    _ 下划线 Underscores __init__
    Page not found (404) 不被Django的exception中间件捕捉 中间件
    从装修儿童房时的门锁说起
    欧拉定理 费马小定理的推广
    线性运算 非线性运算
    Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
    Avoiding Full Table Scans
    批量的单向的ssh 认证
    批量的单向的ssh 认证
    Corrupted MAC on input at /usr/local/perl/lib/site_perl/5.22.1/x86_64-linux/Net/SSH/Perl/Packet.pm l
  • 原文地址:https://www.cnblogs.com/boycelee/p/12595884.html
Copyright © 2011-2022 走看看