这篇文章分析的代码:
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
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 {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//如果不是仅仅做类型检查则是创建bean,这里需要记录 将beanName缓存在alreadyCreatedz中
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 从容器中获取 beanName 相应的 GenericBeanDefinition,并将其转换为 RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查给定的合并的 BeanDefinition
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//获取depends-on的属性值,如果depends-on的值存在 则添加进入dependentBeanMap缓存中
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. isPrototypeCurrentlyInCreation方法
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set>) curVal).contains(beanName))));
}
Spring对于处于原型模式的正在创建的bean的依赖会抛出异常。
2.pareentBeanFactory加载
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取原始name
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
//加入parentBeanFactory是AbstractBeanFactory类型
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
//args不为空情况下,委托方法
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
////标准情况下,委托方法
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
如果beanDefinitionMap没有包含beanName对应的BeanDefinition,则从parentBeanFactory中加载。
originalBeanName()方法作用:如果name是以&开头的,那么beanName也要加上这个标志。
3.类型检查
参数typeCheckOnly判断bean是否为类型检查获取bean。如果不是则需要调用markBeanAsCreated()缓存起来.
protected void markBeanAsCreated(String beanName) {
//判断已创建是否包含beanName
if (!this.alreadyCreated.contains(beanName)) {
// 获取全局锁
synchronized (this.mergedBeanDefinitions) {
//双重判断
if (!this.alreadyCreated.contains(beanName)) {
// 从 mergedBeanDefinitions 中删除 beanName,
// 并在下次访问时重新创建它。
clearMergedBeanDefinition(beanName);
// 添加到已创建bean 集合中
this.alreadyCreated.add(beanName);
}
}
}
}
4. 获取RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
getMergedLocalBeanDefinition():作用主要是将获取beanName对应的RootBeanDefinition对象
checkMergedBeanDefinition()则是检查创建的RootBeanDefinition对象。
5.处理depends-on
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//获取depends-on的属性值,如果depends-on的值存在 则添加进入dependentBeanMap缓存中
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);
}
}
}
// 单例模式下创建bean
处理bean的依赖思路大致是:
isDependent方法:检测beaName和dependsOn是否存在已存在依赖。
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set alreadySeen) {
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
//获取原始的beanName
String canonicalName = canonicalName(beanName);
//获取beaName的依赖集合
Set dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
//包含,则证明已经处于注册依赖
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
//递归检测
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
registerDependentBean方法注册bean的依赖关系
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
将依赖映射关系保存:dependentBeanMap、dependenciesForBeanMap。
最后调用getBean()实例化bean。