spring 源码分析01

spring中获取bean的常见的方式,通常从BeanFactory中或者ApplicationContext中获取。由于ApplicationContext接口继承了BeanFactory接口,因此直接讲BeanFactory.getBean(String beanName)
AbstractBeanFactory的getBean调用的是该类的doGetBean方法html

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// 从spring的三级缓存中获取bean---解决循环依赖的关键
		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 + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance: // We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

            //忽略部分代码
			.....

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				//忽略部分代码,getDependsOn依赖bean先加载
			    .....

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } 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, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); 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; } } //忽略部分代码--类型的校验 ..... } return (T) bean; } 复制代码

上述的代码中大体的流程以下:spring

  1. 从Spring维护的三级缓存中获取一个singleton bean,获取成功直接返回
  2. 判断该bean是否处于建立中,若是是说明出现了循环依赖,抛异常
  3. 根据bean的做用域,分别用不一样的方式获取bean,若是获取不到最终调用的都是同一个createBean方式
  4. getObjectForBeanInstance 若是上述方法获取到的是一个FactoryBean的状况下,须要从里面获取对应的咱们须要的Bean

下面分析下singleton bean的获取缓存

// Create bean instance.
if (mbd.isSingleton()) {
	sharedInstance = getSingleton(beanName, () -> {
		try {
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
			destroySingleton(beanName);
			throw ex;
		}
	});
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
复制代码
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name 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 + "'");
				}
				beforeSingletonCreation(beanName);
				//定义异常
				...
				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) {
				    //封装异常
					...
				}
				finally {
					...
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}
复制代码
  1. 由于singleton的bean只能存在一个,因此对singletonObjects这个缓存作加锁获取
  2. 作循环依赖判断
  3. beforeSingletonCreation(beanName);//也就是把这个beanName标记成正在建立中
  4. 经过singletonFactory的方法获取bean --> 也就是调用createBean方法
  5. afterSingletonCreation(beanName);//去除该beanName正在建立中的标记
  6. 若是是新建立的singleton的bean的话,把他加入singletonObjects缓存中
  7. 这个singletonObjects缓存也就是上面所说的三级缓存的中的第一级(具体后续再说)

无论是singleton仍是Prototype仍是其余的scope,在从做用域中获取不到bean的状况下,都是调用的createBeanbash

  • 知识点梳理:
  1. FactoryBean:www.cnblogs.com/davidwang45…
  2. bean的做用域:
    1. singleton:整个容器中保留一份
    2. prototype:每次使用的时候,建立新的
    3. 其余scope
      1. SimpleThreadScope
      2. RequestScope
      3. SessionScope
相关文章
相关标签/搜索