书接上文,我们讲完了doGetBean if 流程,下面我们继续康康有什么神奇的代码,废话不多说,show you the codes
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//1 获取 beanName,主要是处理alias 和factorybean的 "&"
final String beanName = transformedBeanName(name);
Object bean;
//2 从缓存中或者实例工厂中获取 bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//3 删除无用的日志代码 通过 getObjectForBeanInstance 获取bean实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 4 检查原型模式
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//5 加载父类容器中,如果父容器不为空,且当前容器中没有改bean,则通过父容器加载
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 6 记录bean已经被创建过
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 7 beanName 相应的 GenericBeanDefinition,并且转换为 RootBeanDefinition,并对其进行检测
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 8 处理所依赖的 bean,这里有如何判断循环依赖的方法
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);
}
}
}
// 9 单例模式的bean 实例化
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 10 如果创建失败执行销毁过程(单例模式下为了解决循环依赖,可能已经提前暴露了该bean)
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 11 原型模式
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 12 其他的scope
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;
}
}
// 13 检查需要的类型是否符合 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.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;
}
1getParentBeanFactory 和循环依赖的处理
- 如果beanName是原型模式,且正在创建中,直接抛出异常
- 如果此时还没拿到bean,则加载父容器,如果父容器不为null 则通过父容器加载并返回bean
- 对bean进行标记,主要是将beanName 添加到
alreadyCreated容器中
protected void markBeanAsCreated(String beanName) {
// 没有创建
if (!this.alreadyCreated.contains(beanName)) {
// 加上全局锁
synchronized (this.mergedBeanDefinitions) {
// 再次检查一次:DCL 双检查模式
if (!this.alreadyCreated.contains(beanName)) {
// 从 mergedBeanDefinitions 中删除 beanName,
// 并在下次访问时重新创建它。
clearMergedBeanDefinition(beanName);
// 添加到已创建bean 集合中
this.alreadyCreated.add(beanName);
}
}
}
}
- 通过
getMergedLocalBeanDefinition获取RootBeanDefinition实例,并进行检查 - 针对单例模式进行依赖的处理
- 首先使用
String[] dependsOn = mbd.getDependsOn()获取当前bean的所有依赖属性 - 通过
isDependent方法判断是否有循环依赖,这里有递归调用,如果没有循环依赖则调用registerDependentBean进行注册,主要是更新表格里的2个Map getBean(dep)是为了加载当前bean依赖的bean
| Map | 作用 |
|---|---|
| dependentBeanMap | 依赖当前bean的集合 |
| dependenciesForBeanMap | 当前Bean所依赖的Bean的集合 存储格式 beanName -> 该bean依赖的bean集合 |
protected boolean isDependent(String beanName, String dependentBeanName) {
synchronized (this.dependentBeanMap) {
return isDependent(beanName, dependentBeanName, null);
}
}
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
// alreadySeen 已经检测到的依赖 bean
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
// 获取原始 beanName 之前讲过我们就不多少了
String canonicalName = canonicalName(beanName);
// 获取当前 beanName 的依赖集合
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
// 不存在依赖,返回false
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;
}
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);
}
}
2 各个作用域bean的获取
2.1 单例bean的获取
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 如果创建失败执行销毁过程(单例模式下为了解决循环依赖,可能已经提前暴露了该bean)
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
书接第一篇Spring IOC 源码之 getBean(一) ,如果缓存中没有我们需要的bean,我们只能从头开始加载bean,那么getSingleton(String beanName, ObjectFactory<?> singletonFactory) 就要粉墨登场啦
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 全局加锁
synchronized (this.singletonObjects) {
// 1 因为 singleton 模式其实就是复用已经创建的 bean 所以这步骤必须检查
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 2 前置处理 省略部分代码
beforeSingletonCreation(beanName);
boolean newSingleton = false;
// 省略代码
try {
// 3 这个过程其实是调用 createBean() 方法
singletonObject = singletonFactory.getObject();
newSingleton = true;
} finally {
// 4 后置处理
afterSingletonCreation(beanName);
}
// 5 加入缓存中
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
// 直接返回
return singletonObject;
}
}
1.this.singletonObjects.get(beanName) 通过缓存获取bean
2. 如果为空, 则通过beforeSingletonCreation(beanName) 进行前置处理,同时定义一个属性newSingleton 为false
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
- 通过
singletonFactory.getObject()获取bean,同时标记为newSingletion - 进行后置处理
- 加入缓存
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);
}
}
2.2 原型模式bean的获取
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
- 调用 beforeSingletonCreation() 记录加载原型模式 bean 之前的加载状态,即前置处理。
- 调用 createBean() 创建一个 bean 实例对象。
- 调用 afterSingletonCreation() 进行加载原型模式 bean 后的后置处理。
- 调用 getObjectForBeanInstance() 从 bean 实例中获取对象。
2.3 其他作用域
其他作用域的偷个懒,暂时不做分析,有兴趣的小伙伴自己自行了解