前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring IOC Notes-Core method analysis

Spring IOC Notes-Core method analysis

作者头像
itliusir
发布2018-12-07 17:30:14
2920
发布2018-12-07 17:30:14
举报
文章被收录于专栏:刘君君

摘要: Spring IOC 学习笔记-核心方法分析

正文:

核心方法分析

scan–>doScan

代码语言:javascript
复制
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
	Assert.notEmpty(basePackages, "At least one base package must be specified");
	// 使用Set可以去重,BeanDefinitionHolder对象已实现equals与hashCode方法
	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
	for (String basePackage : basePackages) {
		 // 扫描basePackage,并将带有@Componet、@ManagedBean(JSR-250)、@Named(JSR-330)的class装载入beanDefinition
		Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
		for (BeanDefinition candidate : candidates) {
			 // 判断Scope,若无则scopeName默认为singleton、scopedProxyMode默认为NO
			ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
			candidate.setScope(scopeMetadata.getScopeName());
			 //生成BeanName,首先会判断@Componet..JSR.,然后未设置则会默认类名首字母小写的beanName
			String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
			if (candidate instanceof AbstractBeanDefinition) {
				  // 初始化candidate默认属性
				postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
			}
			if (candidate instanceof AnnotatedBeanDefinition) {
				  // 判断属性值并赋值
				AnnotationConfigUtils.processCommonDefinitionAnnotations(
					(AnnotatedBeanDefinition) candidate);
			}
			  //检查bean是否已经存在
			if (checkCandidate(beanName, candidate)) {
				BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
				  // 判断scopedProxyMode值确认是否需要代理创建
				definitionHolder =
						AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
				beanDefinitions.add(definitionHolder);
				  // 注册beanDefinitionMap、新增beanDefinitionNames、
				registerBeanDefinition(definitionHolder, this.registry);
			}
		}
	}
	return beanDefinitions;
}

refresh

代码语言:javascript
复制
@Override
public void refresh() throws BeansException, IllegalStateException {
    // 加锁,避免并发refresh
    synchronized (this.startupShutdownMonitor) {
        // 设置startupDate、active(启动状态)、标准环境的初始化、初始化ApplicationEvents
        prepareRefresh();

        // 如果是AnnotationConfigApplicationContext 会在 上个方法 doScan 中进行装载beanDefinitionMap,如果是ClassPathXmlApplicationContext 会在如下方法进行装载beanDefinitionMap
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 设置ClassLoader、beanPostProcessor、registerSingleton(特殊bean)、
        prepareBeanFactory(beanFactory);

        try {
            // 留给子类的扩展点,可以在这里对beanFactory做一些特殊的操作
            postProcessBeanFactory(beanFactory);

            // 接下来就是调用已注册子类的BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注册BeanPostProcessor的实现类,该接口的两个可以扩展的方法:
            // 1. postProcessBeforeInitialization Bean初始化之前执行
            // 2. postProcessAfterInitialization  Bean初始化之后执行
            registerBeanPostProcessors(beanFactory);

            // 注册messageSource
            initMessageSource();

            // 注册SimpleApplicationEventMulticaster(事件广播器),不指定beanName会默认创建,无法自定义
            initApplicationEventMulticaster();

            // 留给子类的扩展点,可以在这里对特殊的bean进行初始化
            onRefresh();

            // 注册ApplicationListener(事件监听器)的实现类
            registerListeners();

            // 实例化所有剩余(非lazy-init)的singleton beans
            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();
        }
    }
}

getBean–>doGetBean

Bean加载的大致流程如下:

  1. 处理 beanName (别名、 FACTORY_BEAN_PREFIX )
  2. 尝试从缓存、singletonFactories 中加载
  3. Bean 的实例化
  4. 初始化依赖部分(若存在)
  5. 针对不同 scope 进行 Bean 的创建
  6. 类型转换
代码语言:javascript
复制
protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
	// 处理beanName(别名、FACTORY_BEAN_PREFIX)
	final String beanName = transformedBeanName(name);
	Object bean;

	// 检查(缓存、singletonFactories)是否已创建
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		if (logger.isDebugEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		 // 如果不是FactoryBean则直接返回,若是则返回getObject();
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// 只有单例情况(缓存、提前暴露ObjectFactory)下才会尝试解决循环依赖,如果是Prototype则直接抛出异常
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// 检查是否已存在
		BeanFactory parentBeanFactory = getParentBeanFactory();
		 // 当前加载的配置是否包含beanName
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// 如果是FactoryBean则标记+&
			String nameToLookup = originalBeanName(name);
			 // 递归父BeanFactory结果
			if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
		}
		// 如果不是仅仅做类型检查(创建 Bean )则要进行记录
		if (!typeCheckOnly) {
			 //alreadyCreated.add(beanName)
			markBeanAsCreated(beanName);
		}

		try {
			 // 转换为 RootBeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				  // 若存在依赖则递归实例化依赖
				for (String dep : dependsOn) {
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					  // 缓存依赖调用->dependentBeanMap(dep,Set<beanName>)
					registerDependentBean(dep, beanName);
					getBean(dep);
				}
			}

			// 如果bean是singleton 则开始创建
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
					@Override
					public Object getObject() throws BeansException {
						try {
							   // 创建bean 见下文详细分析
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					}
				});
				  // 如果不是FactoryBean则直接返回,若是则返回getObject();
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}
			// 如果bean是prototype 则开始创建
			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					  // 创建bean
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				  // 如果不是FactoryBean则直接返回,若是则返回getObject();
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
			// 非singleton和prototype的bean创建
			else {
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						}
					});
					  // 如果不是FactoryBean则直接返回,若是则返回getObject();
					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
							"Scope '" + scopeName + "' is not active for the current thread; consider " +
							"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
							ex);
				}
			}
		}
		catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}

	// 检查类型
	if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
		try {
			return getTypeConverter().convertIfNecessary(bean, requiredType);
		}
		catch (TypeMismatchException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}

getSingleton

单例Bean的创建

  1. 同步
  2. 检查缓存是否已加载过
  3. 记录创建状态
  4. 调用 singletonFactory.getObject() 初始化接口
  5. 删除创建状态
  6. 结果加入缓存( singletonObjectsregisteredSingletons )并清除一些辅助状态缓存( singletonFactoriesearlySingletonObjects )
    • Map<String, Object> singletonObjects 保存 beanName-->beanInstance
    • Map<String, ObjectFactory<?>> singletonFactories 保存 beanName-->ObjectFactory
    • Map<String, Object> earlySingletonObjects 保存 beanName-->beanInstance 在上文 doGetBean() 方法有调用到 Object sharedInstance = getSingleton(beanName)singletonObjects 区别也即是此处,当bean在此处时在创建过程中就可以通过 getBean --> doGetBean() 获取到了
    • Set<String> registeredSingletons 保存 所有已注册的Bean
代码语言:javascript
复制
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "'beanName' must not be null");
    // 同步全局变量
    synchronized (this.singletonObjects) {
        // 有则复用 无则创建
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName,
                                                          "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                                                          "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            // 记录正在创建的状态 -->singletonsCurrentlyInCreation.add(beanName)
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<Exception>();
            }
            try {
                // 初始化
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // Has the singleton object implicitly appeared in the meantime ->
                // if yes, proceed with it since the exception indicates that state.
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw ex;
                }
            }
            catch (BeanCreationException ex) {
                if (recordSuppressedExceptions) {
                    for (Exception suppressedException : this.suppressedExceptions) {
                        ex.addRelatedCause(suppressedException);
                    }
                }
                throw ex;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                // 删除正在创建的状态 -->singletonsCurrentlyInCreation.remove(beanName)
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                // 加入缓存(singletonObjects/registeredSingletons)、清除singletonFactories/earlySingletonObjects
                addSingleton(beanName, singletonObject);
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }
}

createBean–>doCreateBean

从上文中的 doScandoGetBean 的命名方式可以看出,真正干活的都是 doXxx 而创建 Bean 也不例外,真正干活的在 doCreateBean 中 下面是创建 Bean 的流程

  1. 如果是单例,则清除缓存
  2. RootBeanDefinition --> BeanWrapper (初始化默认选择无参构造方法)
  3. 判断是否需要提前暴露
  4. 依赖循环处理,即将A提前放入缓存,依赖A的B在创建时会去缓存拿 ObjectFactory 来创建
  5. 填充属性
  6. 初始化
代码语言:javascript
复制
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {

	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
	mbd.resolvedTargetType = beanType;

	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}

	// 是否需要提前暴露,是否单例&允许循环依赖(default:true)&正在创建状态(参考上文的getSingleton()-->beforeSingletonCreation(beanName);)
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isDebugEnabled()) {
			logger.debug("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		 // 将创建实例先存入ObjectFactory
		addSingletonFactory(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				  // 若没有InstantiationAwareBeanPostProcessors则直接返回
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		 // 对bean属性注入,若依赖别的Bean则递归初始化依赖Bean
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			 /**
			  *  初始化
			  *  想起了生命周期没 /滑稽
			  * 1. BeanPostProcessor.postProcessBeforeInitialization
			  * 2. InitializingBean.afterPropertiesSet
			  * 3. init-method
			  * 4. BeanPostProcessor.postProcessAfterInitialization
			  */
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}

	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			  // 判断是否增强 (即在initializeBean()中有没有被改变)
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			  // 判断当前Bean被其他Bean所依赖
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				  // 若互相依赖不一致则抛异常
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName,
							"抛异常");
				}
			}
		}
	}

	// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-11-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文:
  • 核心方法分析
    • scan–>doScan
      • refresh
        • getBean–>doGetBean
          • getSingleton
            • createBean–>doCreateBean
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档