SpringBoot 源码解析6:Bean的创建① AbstractBeanFactory#doGetBean

1.概述

  1. AbstractBeanFactory#doGetBean方法是Spring创建Bean的核心方法。在此之前Spring已经将BeanDefinition注册到了DefaultListableBeanFactory#beanDefinitionMap。而doGetBean方法会根据BeanDefinition实例化Bean,并且初始化Bean的属性。
  2. AbstractBeanFactory#doGetBean方法是获取Bean的核心入口方法。如果单例池中存在,则返回Bean;不存在,则创建Bean。

2. AbstractBeanFactory#doGetBean源码分析

/**
 * Return an instance, which may be shared or independent, of the specified bean.
 * @param name the name of the bean to retrieve
 * @param requiredType the required type of the bean to retrieve
 * @param args arguments to use when creating a bean instance using explicit arguments
 * (only applied when creating a new instance as opposed to retrieving an existing one)
 * @param typeCheckOnly whether the instance is obtained for a type check,
 * not for actual use
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
		@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

	// 1.转换Bean的名称
	final String beanName = transformedBeanName(name);
	Object bean;

	// Eagerly check singleton cache for manually registered singletons.
	// 2.先校验单例Bean是否已存在,或者手动创建了单例。存在的bean会放在singletonObjects(单例池)中
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		if (logger.isTraceEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		// 2.1. 从Bean的实例里面获取对象,这里体现了对FactoryBean的兼容性
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		// 如果当前的Bean没有被实例化,假设在循环依赖里面
		// 3. 循环依赖是不循序原型模式的
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// Check if bean definition exists in this factory.
		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 4.如果当前的Bean工厂中没有注册BeanDefinition,就委派父Bean工厂去实例化
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		if (!typeCheckOnly) {
			// 5.标记当前Bean已创建
			markBeanAsCreated(beanName);
		}

		try {
			// 6.合并BeanDefinition,将当前的BeanDefinition与当前BeanDefinition中的parentName所指向的BeanDefinition的属性合并。当前的属性覆盖父BeanDefinition的属性
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			// 7.校验BeanDefinition
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			// 8.处理依赖关系,@DependsOn注解
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				// 8.1.存在依赖的Bean,就先去加载需要依赖的Bean
				for (String dep : dependsOn) {
					// 8.2.判断是否存在循环依赖
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// 8.3.保存Bean的依赖关系
					registerDependentBean(dep, beanName);
					try {
						//8.4.创建所依赖的Bean
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// Create bean instance.
			// 9.创建Bean,单例、原型、其他
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, () -> {
					try {
						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;
					}
				});
				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;
		}
	}

	// Check if required type matches the type of the actual bean instance.
	// 10.校验从Spring中获取的Bean与用户限定的类型是否一致,不一致则抛出异常
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return convertedBean;
		}
		catch (TypeMismatchException ex) {
			if (logger.isTraceEnabled()) {
				logger.trace("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}
  1. 转换Bean的名称,先去掉beanName前缀&,再使用别名获取bean。如果是FactoryBean,那么bean的名称是以"&"开头的。
  2. getObjectForBeanInstance:兼容FactoryBean
    2.1. 跟普通的bean一样,FactoryBean类型的单例创建完毕之后都会保存到单例池。
    2.2. 校验单例Bean是否已存在,存在有两种情况:
    情况1:第一种情况是手动注册到单例池,比如调用DefaultSingletonBeanRegistry#registerSingleton。
    情况2:通过BeanDefinition创建单例。
    但是,不管是哪种情况,创建成功之后都可以通过DefaultSingletonBeanRegistry#getSingleton从Spring的三级缓存中获取。
    2.3. getObjectForBeanInstance方法,通过bean的名称获取bean。
  3. 在Spring中原型模式是不允许循环依赖的。因为ClassA 和 ClassB循环依赖,创建对象的过程为 A1 -> B1 -> A2 -> B2 -> A3 -> B3 -> B4…这样就无法完成Bean的属性的初始化。
  4. 如果当前的Bean工厂中没有注册BeanDefinition,就委派父Bean工厂去实例化。递归。
  5. 标记当前Bean已创建,后面对属性的初始化、代理、三级缓存获取等很多地方都用到了这个标识。
  6. 合并BeanDefinition,将当前的BeanDefinition与当前BeanDefinition中的parentName所指向的BeanDefinition的属性合并。当前的属性覆盖父BeanDefinition的属性。
  7. 校验BeanDefinition,校验了是否为Abstract。
  8. 处理dependsOn。
    8.1 @DependsOn属性解析在AnnotationConfigUtils#processCommonDefinitionAnnotations中完成的。SpringBoot 源码解析5:ConfigurationClassPostProcessor整体流程和@ComponentScan源码分析
    8.2 如果有DependsOn,那么就先实例化DependsOn,两个Bean是不能相互DependsOn。调用getBean方法将所有依赖的Bean创建完毕之后,才创建当前的Bean。注册和校验Bean的依赖关系是通过两个缓存dependentBeanMap和dependenciesForBeanMap完成的。
  9. 支持单例、原型、scope三种方式创建Bean。
  10. 校验通过beanName创建的Bean与限定的类型是否一致,不一致就会抛出异常。因为Spring提供了同时支持beanName和beanType获取Bean。

2.1 转换bean的名称 transformedBeanName

protected String transformedBeanName(String name) {
	return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

//BeanFactoryUtils.transformedBeanName
public static String transformedBeanName(String name) {
	Assert.notNull(name, "'name' must not be null");
	if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
		return name;
	}
	return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
		do {
			beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
		}
		while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
		return beanName;
	});
}

public String canonicalName(String name) {
	String canonicalName = name;
	// Handle aliasing...
	String resolvedName;
	do {
		resolvedName = this.aliasMap.get(canonicalName);
		if (resolvedName != null) {
			canonicalName = resolvedName;
		}
	}
	while (resolvedName != null);
	return canonicalName;
}
  1. 在循环里面将beanName去除所有以"&"开头的字符,添加了缓存transformedBeanNameCache。
  2. 通过去除"&"之后的名称,获取别名。

2.2. FactoryBean兼容

2.2.1 getObjectForBeanInstance
protected Object getObjectForBeanInstance(
		Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

	// Don't let calling code try to dereference the factory if the bean isn't a factory.
	//如果是以&开头,那么需要获取的bean就是factoryBean。
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		if (beanInstance instanceof NullBean) {
			return beanInstance;
		}
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
		}
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		return beanInstance;
	}

	// Now we have the bean instance, which may be a normal bean or a FactoryBean.
	// If it's a FactoryBean, we use it to create a bean instance, unless the
	// caller actually wants a reference to the factory.
	// 如果不是普通的bean,就直接返回
	if (!(beanInstance instanceof FactoryBean)) {
		return beanInstance;
	}

	Object object = null;
	if (mbd != null) {
		mbd.isFactoryBean = true;
	}
	else {
		//对factoryBean进行缓存,体现了单例factoryBean的特性
		object = getCachedObjectForFactoryBean(beanName);
	}
	if (object == null) {
		// Return bean instance from factory.
		FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
		// Caches object obtained from FactoryBean if it is a singleton.
		if (mbd == null && containsBeanDefinition(beanName)) {
			mbd = getMergedLocalBeanDefinition(beanName);
		}
		boolean synthetic = (mbd != null && mbd.isSynthetic());
		//回调factoryBean#getObject获取Bean
		object = getObjectFromFactoryBean(factory, beanName, !synthetic);
	}
	return object;
}
  1. 参数说明
    beanInstance:从单例池中获取的bean,这个bean可能是factoryBean
    name:通过getBean方法想要获取bean的名称
    beanName: name去除所有&前缀之后的名称
    mbd: bean的定义信息
  2. 获取factoryBean:用户可以获取factoryBean这个对象,也可以获取factoryBean#getObject方法的返回值的对象。
    1. 如果传入的bean的name是普通的,即不以&开头,获取的对象就是回调factoryBean#getObject方法的返回值,这也是FactoryBean的特性。
    2. 当然,如果用户一定要获取FactoryBean的对象,Spring也是支持的。如果beanName是以&开头,那么Spring就认为用户要获取的对象一定是FactoryBean,即不会回调factoryBean#getObject。并且Spring还校验了这个bean的类型一定是FactoryBean,否则会抛出BeanIsNotAFactoryException。
  3. 如何支持单例:因为每一次调用factoryBean#getObject返回的对象地址是不一样的,为了保证获取的对象是单例,添加了缓存FactoryBeanRegistrySupport#factoryBeanObjectCache。
2.2.2 FactoryBeanRegistrySupport#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
	if (factory.isSingleton() && containsSingleton(beanName)) {
		synchronized (getSingletonMutex()) {
			Object object = this.factoryBeanObjectCache.get(beanName);
			if (object == null) {
				object = doGetObjectFromFactoryBean(factory, beanName);
				// Only post-process and store if not put there already during getObject() call above
				// (e.g. because of circular reference processing triggered by custom getBean calls)
				Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
				if (alreadyThere != null) {
					object = alreadyThere;
				}
				else {
					if (shouldPostProcess) {
						if (isSingletonCurrentlyInCreation(beanName)) {
							// Temporarily return non-post-processed object, not storing it yet..
							return object;
						}
						beforeSingletonCreation(beanName);
						try {
							object = postProcessObjectFromFactoryBean(object, beanName);
						}
						catch (Throwable ex) {
							throw new BeanCreationException(beanName,
									"Post-processing of FactoryBean's singleton object failed", ex);
						}
						finally {
							afterSingletonCreation(beanName);
						}
					}
					if (containsSingleton(beanName)) {
						this.factoryBeanObjectCache.put(beanName, object);
					}
				}
			}
			return object;
		}
	}
	else {
		Object object = doGetObjectFromFactoryBean(factory, beanName);
		if (shouldPostProcess) {
			try {
				object = postProcessObjectFromFactoryBean(object, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
			}
		}
		return object;
	}
}
  1. 这是从FactoryBean获取Bean具体方法。
  2. 分为单例和非单例。如果是单例,使用了缓存。非单例,就没有放入缓存,直接创建bean。FactoryBean#getObject具体回调是在FactoryBeanRegistrySupport#doGetObjectFromFactoryBean中完成的。
2.2.3 Demo

虽然本系列只是做源码分析,还是写一个demo吧!!!

FactoryBean

@Component
public class FactoryBeanTest implements FactoryBean<Object> {

    @Override
    public Object getObject() throws Exception {
        return new Object();
    }

    @Override
    public Class<?> getObjectType() {
        return Object.class;
    }
}

启动类

public static void main(String[] args) {
     ConfigurableApplicationContext run = SpringApplication.run(MyApplication.class, args);
     Object obj = run.getBean("factoryBeanTest");
     System.out.println(obj.getClass());
     Object factoryBean = run.getBean("&factoryBeanTest");
     System.out.println(factoryBean.getClass());
 }

可以看到,factoryBeanTest打印的是回调getObject之后的bean,而&factoryBeanTest打印的就是FactoryBean的本身。

在这里插入图片描述

2.3 三级缓存

2.3.1 属性
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

这三个Map的key都为beanName

  1. singletonObjects :一级缓存,存放的值为Bean。并且bean中的属性已初始化完毕。@Autowired、@Resource注解处理完毕。
  2. earlySingletonObjects : 二级缓存,存放的为Bean。但是Bean中的属性可能没有初始化,也有可能初始化了一部分。
  3. singletonFactories :三级缓存,存放的为ObjectFactory。通过源码看ObjectFactory是FunctionalInterface。回调该函数式接口才能返回Bean。

面试题:为什么需要三级缓存singletonFactories?代理。三级缓存里面判断是否有代理对象,有代理对象就返回单例对象(没有就返回当前对象),放入到二级缓存。AbstractAutoProxyCreator#earlyProxyReferences中缓存了代理的对象。

2.3.2 从缓存中获取
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	//1.从一级缓存中获取Bean
	Object singletonObject = this.singletonObjects.get(beanName);
	//一级缓存中不存在,并且当前的Bean是单例并且正在创建中
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		synchronized (this.singletonObjects) {
			//2.从二级缓存中获取
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				//3.获取三级缓存
				ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
				if (singletonFactory != null) {
					//回调三级缓存
					singletonObject = singletonFactory.getObject();
					//放入三级缓存
					this.earlySingletonObjects.put(beanName, singletonObject);
					//移除二级缓存
					this.singletonFactories.remove(beanName);
				}
			}
		}
	}
	return singletonObject;
}

源码解析如注释。逐级获取, 一级缓存 -> 二级缓存 -> 三级缓存。
三级缓存是FunctionalInterface,如下

@FunctionalInterface
public interface ObjectFactory<T> {

	/**
	 * Return an instance (possibly shared or independent)
	 * of the object managed by this factory.
	 * @return the resulting instance
	 * @throws BeansException in case of creation errors
	 */
	T getObject() throws BeansException;

}
2.3.3 添加缓存
/**
 * Add the given singleton object to the singleton cache of this factory.
 * <p>To be called for eager registration of singletons.
 * @param beanName the name of the bean
 * @param singletonObject the singleton object
 */
protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		//添加一级缓存,移除二级、三级缓存
		this.singletonObjects.put(beanName, singletonObject);
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}

/**
 * Add the given singleton factory for building the specified singleton
 * if necessary.
 * <p>To be called for eager registration of singletons, e.g. to be able to
 * resolve circular references.
 * @param beanName the name of the bean
 * @param singletonFactory the factory for the singleton object
 */
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(singletonFactory, "Singleton factory must not be null");
	synchronized (this.singletonObjects) {
		if (!this.singletonObjects.containsKey(beanName)) {
			this.singletonFactories.put(beanName, singletonFactory);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
}
  1. addSingleton添加一级缓存,将二级、三级缓存清除。
  2. addSingletonFactory添加三级缓存,首先判断了一级缓存中是否存在,不存在则添加三级缓存,并且移除二级缓存。
  3. 可以简单的理解为同一时间只会保存在一个缓存。

ObjectFactory是一个函数接口:

@FunctionalInterface
public interface ObjectFactory<T> {
	T getObject() throws BeansException;
}

三级缓存中保存的是getEarlyBeanReference方法:

if (earlySingletonExposure) {
	if (logger.isTraceEnabled()) {
		logger.trace("Eagerly caching bean '" + beanName +
				"' to allow for resolving potential circular references");
	}
	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

可以看到回调了SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference方法:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	Object exposedObject = bean;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
			}
		}
	}
	return exposedObject;
}

AbstractAutoProxyCreator#getEarlyBeanReference可以获取代理对象。

2.4 @DependsOn原理

2.4.1 @DependsOn注解解析

扫描到一个Bean需要被Spring管理后,就会生成Bean的定义信息,也就是BeanDefinition。而DependsOn的属性也会封装到BeanDefinition中。

想要知道一个Bean是否要被Spring管理,请参考@ComponentScan原理。SpringBoot 源码解析5:ConfigurationClassPostProcessor整体流程和@ComponentScan源码分析

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
	AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
	if (lazy != null) {
		abd.setLazyInit(lazy.getBoolean("value"));
	}
	else if (abd.getMetadata() != metadata) {
		lazy = attributesFor(abd.getMetadata(), Lazy.class);
		if (lazy != null) {
			abd.setLazyInit(lazy.getBoolean("value"));
		}
	}

	if (metadata.isAnnotated(Primary.class.getName())) {
		abd.setPrimary(true);
	}
	AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
	if (dependsOn != null) {
		abd.setDependsOn(dependsOn.getStringArray("value"));
	}

	AnnotationAttributes role = attributesFor(metadata, Role.class);
	if (role != null) {
		abd.setRole(role.getNumber("value").intValue());
	}
	AnnotationAttributes description = attributesFor(metadata, Description.class);
	if (description != null) {
		abd.setDescription(description.getString("value"));
	}
}

可以看到最终将DependsOn#value中的属性封装到AbstractBeanDefinition#dependsOn。而这些属性就是bean的名称。

2.4.2 depends属性应用
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 + "'");
		}
		registerDependentBean(dep, beanName);
		try {
			getBean(dep);
		}
		catch (NoSuchBeanDefinitionException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
		}
	}
}
  1. 如果两个bean相互依赖,就会抛出异常。因为Spring的规则就是dependsOn的bean要先创建,如果相互依赖,Spring不知道优先创建哪一个bean。
  2. 在创建Bean的时候AbstractBeanFactory#doGetBean方法会优先加载AbstractBeanDefinition#dependsOn对应的bean,再创建当前的bean。
2.4.3 依赖关系管理 DefaultSingletonBeanRegistry#registerDependentBean
public void registerDependentBean(String beanName, String dependentBeanName) {
	String canonicalName = canonicalName(beanName);

	synchronized (this.dependentBeanMap) {
		Set<String> dependentBeans =
				this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
		if (!dependentBeans.add(dependentBeanName)) {
			return;
		}
	}

	synchronized (this.dependenciesForBeanMap) {
		Set<String> dependenciesForBean =
				this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
		dependenciesForBean.add(canonicalName);
	}
}
  1. 参数说明:
    beanName:依赖的bean名称
    dependentBeanName:当前正在创建的bean的名称
  2. Spring对一个Bean的依赖关系也进行了管理。其实不仅仅是对@DependsOn注解的关系,一个Bean的属性依赖另外一个bean也是通过这种方式进行管理的。
  3. 这种关系通过两个map进行管理。
    dependentBeanMap:如果A依赖B,那么key为B,value为A。
    dependenciesForBeanMap:如果A依赖B,那么key为A,value为B。
  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值