这篇来看一下getBean里面怎么走,在finishBeanFactoryInitialization方法之前有一个
invokeBeanFactoryPostProcessors方法中就有getBean方法。getBean中实际真正工作的是doGetBean,点进去,先贴一下这个方法
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
/**
* 提取对应的beanName,很多同学可能会认为此处直接使用即可,为什么还要进行转换呢,原因在于当bean对象实现FactoryBean接口之后就会变成&beanName,同时如果存在别名,也需要把别名进行转换*/
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/**提前检查单例缓存中是否有手动注册的单例对象,跟循环依赖有关联*/
Object sharedInstance = getSingleton(beanName);
// 如果bean的单例对象找到了,且没有创建bean实例时要使用的参数
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 + "'");
}
}
// 返回对象的实例,很多同学会理解不了这句话存在的意义,当你实现了FactoryBean接口的对象,需要获取具体的对象的时候就需要此方法来进行获取了
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);
}
// Check if bean definition exists in this factory.
// 如果bean定义不存在,就检查父工厂是否有
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】
String nameToLookup = originalBeanName(name);
// 如果父工厂是AbstractBeanFactory的实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 调用父工厂的doGetBean方法,就是该方法。【递归】
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
// 如果有创建bean实例时要使用的参数
// Delegation to parent with explicit args. 使用显示参数委派给父工厂
// 使用父工厂获取该bean对象,通bean全类名和创建bean实例时要使用的参数
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。
// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 使用父工厂获取bean,通过bean全类名
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 如果不是做类型检查,那么表示要创建bean,此处在集合中做一个记录
// typeCheckOnly字段用于指示BeanFactory是否仅仅对Bean的类型进行检查
if (!typeCheckOnly) {
// 为beanName标记为已经创建(或将要创建)
markBeanAsCreated(beanName);
}
try {
// 此处做了BeanDefinition对象的转换,当我们从xml文件中加载beandefinition对象的时候,封装的对象是GenericBeanDefinition,
// 此处要做类型转换,如果是子类bean的话,会合并父类的相关属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查mbd的合法性,不合格会引发验证异常
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 如果存在依赖的bean的话,那么则优先实例化依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 如果存在依赖,则需要递归实例化依赖的bean
for (String dep : dependsOn) {
// 如果beanName已注册依赖于dependentBeanName的关系
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册各个bean的依赖关系,方便进行销毁
registerDependentBean(dep, beanName);
try {
// 递归优先实例化被依赖的Bean
getBean(dep);
}
// 捕捉为找到BeanDefinition异常:'beanName'依赖于缺少的bean'dep'
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 创建bean的实例对象
if (mbd.isSingleton()) {
// 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:
sharedInstance = getSingleton(beanName, () -> {
try {
// 为给定的合并后BeanDefinition(和参数)创建一个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.
// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除
// 接收到该Bean临时引用的任何Bean
// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
destroySingleton(beanName);
// 重新抛出ex
throw ex;
}
});
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型模式的bean对象创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
// 它是一个原型 -> 创建一个新实例
// 定义prototype实例
Object prototypeInstance = null;
try {
// 创建Prototype对象前的准备工作,默认实现将beanName添加到prototypesCurrentlyInCreation中
beforePrototypeCreation(beanName);
// 为mbd(和参数)创建一个bean实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
afterPrototypeCreation(beanName);
}
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 指定的scope上实例化bean
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
// 从scopes中获取scopeName对于的Scope对象
Scope scope = this.scopes.get(scopeName);
// 如果scope为null
if (scope == null) {
// 抛出非法状态异常:没有名为'scopeName'的scope注册
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 从scope中获取beanName对应的实例对象
Object scopedInstance = scope.get(beanName, () -> {
// 创建Prototype对象前的准备工作,默认实现 将beanName添加到prototypesCurrentlyInCreation中
beforePrototypeCreation(beanName);
try {
// 为mbd(和参数)创建一个bean实例
return createBean(beanName, mbd, args);
}
finally {
// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
afterPrototypeCreation(beanName);
}
});
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
// 捕捉非法状态异常
// 抛出Bean创建异常:作用域 'scopeName' 对于当前线程是不活动的;如果您打算从单个实例引用它,请考虑为此
// beanDefinition一个作用域代理
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) {
// 捕捉获取Bean对象抛出的Bean异常
// 在Bean创建失败后,对缓存的元数据执行适当的清理
cleanupAfterBeanCreationFailure(beanName);
// 重新抛出ex
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 检查requiredType是否与实际Bean实例的类型匹配
// 如果requiredType不为null&&bean不是requiredType的实例
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 获取此BeanFactory使用的类型转换器,将bean转换为requiredType
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
// 如果convertedBean为null
if (convertedBean == null) {
// 抛出Bean不是必要类型的异常
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
// 返回convertedBean
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());
}
}
// 将bean返回出去
return (T) bean;
}
先看这个方法transformedBeanName(name);,主要是做对beanName的处理,因为有时候传进来的beanName带有&的前缀,看下面的源码,如果不带&直接返回beanName,如果没有则进行截取操作返回对应的beanName
protected String transformedBeanName(String name) {
// 去除开头的'&'字符,返回剩余的字符串得到转换后的Bean名称,然后通过递归形式在aliasMap【别名映射到规范名称集合】中得到最终的规范名称
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
点进BeanFactoryUtils.transformedBeanName(name)
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
// 如果beanName不以&开头,则直接返回
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 从transformedBeanNameCache中获取bean名对应的转换后的名称
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
// 从beanName的开头位置去掉'&',并重新赋值给beanName,再重新检查是还是以'&'开头,是的话就再截
// 知道开头不是以'&'开头后,加入到transformedBeanNameCache中
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
再看一下getSingleton(beanName);,点进去,
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中获取对象
Object singletonObject = this.singletonObjects.get(beanName);
//如果一级缓存中没有这个对象,并且当前对象在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//从二级缓存中获取这个对象
singletonObject = this.earlySingletonObjects.get(beanName);
return singletonObject;
}
}
return singletonObject != null ? singletonObject:null;
}
从代码中可以看出,先从缓存中获取,分别从一级缓存,二级缓存,三级缓存中获取,因为之前并没有创建号的对象,所以这里的一级缓存为空,下面是判断条件中的isSingletonCurrentlyInCreation方法
public boolean isSingletonCurrentlyInCreation(String beanName) {
// 从当前正在创建的bean名称set集合中判断beanName是否在集合中
return this.singletonsCurrentlyInCreation.contains(beanName);
}
可以看到正在走到这里的bean都会被放到singletonsCurrentlyInCreation集合中。这一步还是很有必要性的。的那个需要这个bean的时候,根据状态判断走什么
显然上面不是正在创建中,所以直接走到下面,返回空
接着走下面这段代码
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 + "'");
}
}
// 返回对象的实例,很多同学会理解不了这句话存在的意义,当你实现了FactoryBean接口的对象,需要获取具体的对象的时候就需要此方法来进行获取了
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);
}
因为sharedInstance为空,所以这里进入else,点进isPrototypeCurrentlyInCreation,从名字可以看出,他是判断是否原型并且正在创建中,以下是他的源码
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
// 获取当前正在创建的bean名称【线程本地】
Object curVal = this.prototypesCurrentlyInCreation.get();
// 如果当前正在创建的bean名称不为null,且 (当前正在创建的bean名称等于beanName或者当前正在创建的bean名称是Set集合,并包含该beanName)
// 就返回true,表示在当前线程内,beanName当前正在创建中。
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}
BeanFactory parentBeanFactory = getParentBeanFactory();
从名字可以看出可以获取到父容器,并且当前容器没有这个beanName对应的beanDefinition,,就由父容器创建对象,继续往下走
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】
String nameToLookup = originalBeanName(name);
// 如果父工厂是AbstractBeanFactory的实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 调用父工厂的doGetBean方法,就是该方法。【递归】
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
// 如果有创建bean实例时要使用的参数
// Delegation to parent with explicit args. 使用显示参数委派给父工厂
// 使用父工厂获取该bean对象,通bean全类名和创建bean实例时要使用的参数
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。
// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 使用父工厂获取bean,通过bean全类名
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
因为没有父容器,所以这里的方法体不进去,继续往下走
//typeCheckOnly字段用于指示BeanFactory是否仅仅对Bean的类型进行检查,而不进行实际的Bean实例化过程。
if (!typeCheckOnly) {
// 为beanName标记为已经创建(或将要创建)
markBeanAsCreated(beanName);
}
这边typeCheckOnly传进来是false,所以进入方法体markBeanAsCreated
protected void markBeanAsCreated(String beanName) {
// 如果beanName还没有创建
if (!this.alreadyCreated.contains(beanName)) {
// 同步,使用mergedBenDefinitions作为锁
synchronized (this.mergedBeanDefinitions) {
// 如果beanName还没有创建
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
// 在我们实际创建时,重新合并bean定义,以防万一期间的某些元数据发生了变化
// 删除beanName合并bean定义,在下次访问时重新创建
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
先判断alreadyCreated集合中是否有这个beanName的对象,如果没有则放入这个集合中。
接着往下走
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查mbd的合法性,不合格会引发验证异常
checkMergedBeanDefinition(mbd, beanName, args);
获取合并父类的beanDefinition,并检查是否合法。这里的beanDefinition并不是每次需要的时候都需要去merge的,获取一次之后就会被放到缓存中,下次需要的时候直接从缓存中取。当然这个beanDefinition被存储后可能会发生修改,所以取到beanDefinition还要判断mbd.stale字段是true还是false,如果是true那就说明被修改过了,需要再次获取。如下面的代码
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 首先以最小的锁定快速检测并发映射。
// 从bean名称映射到合并的RootBeanDefinition的集合中获取beanName对应的RootBeanDefinition
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
// 如果mbd不为null 且 不需要重新合并定义
if (mbd != null && !mbd.stale) {
// 返回对应的RootBeanDefinition
return mbd;
}
// 获取beanName对应的合并Bean定义,如果beanName对应的BeanDefinition是子BeanDefinition,
// 则通过与父级合并返回RootBeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
接着往下走
String[] dependsOn = mbd.getDependsOn();
就是获取该bean所依赖的bean
继续往下走
if (dependsOn != null) {
// 如果存在依赖,则需要递归实例化依赖的bean
for (String dep : dependsOn) {
// 如果beanName已注册依赖于dependentBeanName的关系
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册各个bean的依赖关系,方便进行销毁
registerDependentBean(dep, beanName);
try {
// 递归优先实例化被依赖的Bean
getBean(dep);
}
// 捕捉为找到BeanDefinition异常:'beanName'依赖于缺少的bean'dep'
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
因为dependsOn为空,所以直接跳过
继续往下走
// Create bean instance.
// 创建bean的实例对象
if (mbd.isSingleton()) {
// 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:
sharedInstance = getSingleton(beanName, () -> {
try {
// 为给定的合并后BeanDefinition(和参数)创建一个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.
// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除
// 接收到该Bean临时引用的任何Bean
// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
destroySingleton(beanName);
// 重新抛出ex
throw ex;
}
});
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
beanDefinition是单例,往里走,可以看到里面的getSingleton和之前的不太一样,里面传进去一个方法体,点进去看一下
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// 如果beanName为null,抛出异常
Assert.notNull(beanName, "Bean name must not be null");
// 使用单例对象的高速缓存Map作为锁,保证线程同步
synchronized (this.singletonObjects) {
// 从单例对象的高速缓存Map中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 如果单例对象获取不到
if (singletonObject == null) {
// 如果当前在destorySingletons中
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);
// 表示生成了新的单例对象的标记,默认为false,表示没有生成新的单例对象
boolean newSingleton = false;
// 有抑制异常记录标记,没有时为true,否则为false
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
// 如果没有抑制异常记录
if (recordSuppressedExceptions) {
// 对抑制的异常列表进行实例化(LinkedHashSet)
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 从单例工厂中获取对象
singletonObject = singletonFactory.getObject();
// 生成了新的单例对象的标记为true,表示生成了新的单例对象
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.
// 同时,单例对象是否隐式出现 -> 如果是,请继续操作,因为异常表明该状态
// 尝试从单例对象的高速缓存Map中获取beanName的单例对象
singletonObject = this.singletonObjects.get(beanName);
// 如果获取失败,抛出异常
if (singletonObject == null) {
throw ex;
}
}
// 捕捉Bean创建异常
catch (BeanCreationException ex) {
// 如果没有抑制异常记录
if (recordSuppressedExceptions) {
// 遍历抑制的异常列表
for (Exception suppressedException : this.suppressedExceptions) {
// 将抑制的异常对象添加到 bean创建异常 中,这样做的,就是相当于 '因XXX异常导致了Bean创建异常‘ 的说法
ex.addRelatedCause(suppressedException);
}
}
// 抛出异常
throw ex;
}
finally {
// 如果没有抑制异常记录
if (recordSuppressedExceptions) {
// 将抑制的异常列表置为null,因为suppressedExceptions是对应单个bean的异常记录,置为null
// 可防止异常信息的混乱
this.suppressedExceptions = null;
}
// 创建单例后的回调,默认实现将单例标记为不在创建中
afterSingletonCreation(beanName);
}
// 生成了新的单例对象
if (newSingleton) {
// 将beanName和singletonObject的映射关系添加到该工厂的单例缓存中:
addSingleton(beanName, singletonObject);
}
}
// 返回该单例对象
return singletonObject;
}
}
Object singletonObject = this.singletonObjects.get(beanName);从一级缓存中获取该beanName对应的对象
if (singletonObject == null)因为singletonObject为空,所以进入,
if (this.singletonsCurrentlyInDestruction),判断是否正在销毁singleton
beforeSingletonCreation(beanName);在singleton创建之前做的一些工作,点进去
protected void beforeSingletonCreation(String beanName) {
// 如果当前在创建检查中的排除bean名列表中不包含该beanName且将beanName添加到当前正在创建的bean名称列表后,出现
// beanName已经在当前正在创建的bean名称列表中添加过
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
// 抛出当前正在创建的Bean异常
throw new BeanCurrentlyInCreationException(beanName);
}
}
如果在创建检查中没有beanName对应的bean,并且将beanName添加到当前正在创建的bean名称列表后失败,就会进入下面的跑出异常。可以看到在这里是做了检查并将beanName加入到singletonsCurrentlyInCreation列表中。
继续往下走
singletonObject = singletonFactory.getObject();执行这个方法参考ObjectFactory中的getObject方法。ObjectFactory是一个函数式接口,当调用其中的getObject方法的时候,才会执行传递进来的匿名内部类。按照这个逻辑,我们调用singletonFactory.getObject();走到匿名内部类的createBean(beanName, mbd, args);
继续往里走
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 锁定class,根据设置的class属性或者根据className来解析class
//提供的mbd(即BeanDefinition)和beanName解析出对应的Class对象。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 进行条件筛选,重新赋值RootBeanDefinition,并设置BeanClass属性
//resolvedClass != null:确定已经成功将BeanDefinition中指定的类名转换成了Class对象。这意味着Spring已经能够确切知道要创建哪个类的实例。
//!mbd.hasBeanClass():表示当前的BeanDefinition并没有直接与一个Class对象关联起来,换句话说,虽然我们可能知道了类的名称,但BeanDefinition还没有更新为具体的类实例。
//mbd.getBeanClassName() != null:确保BeanDefinition中确实存有类名存在。这是基本的前提,有了具体的类名才能进一步进行类的加载和解析。
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 重新创建一个RootBeanDefinition对象
mbdToUse = new RootBeanDefinition(mbd);
// 设置BeanClass属性值
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 验证及准备覆盖的方法,lookup-method replace-method,当需要创建的bean对象中包含了lookup-method和replace-method标签的时候,会产生覆盖操作
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 实际创建bean的调用
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
点进resolveBeanClass(mbd, beanName);
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
// 判断mbd的定义信息中是否包含beanClass,并且是Class类型的,如果是直接返回,否则的话进行详细的解析
if (mbd.hasBeanClass()) {
// 如果mbd指定了bean类
return mbd.getBeanClass();
}
// 判断是否有安全管理器
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
// 进行详细的处理解析过程
return doResolveBeanClass(mbd, typesToMatch);
}
}
catch (PrivilegedActionException pae) {
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
先判断当前的benaDefinition的Beanclass字段是否有Class,有的话直接返回。
接着判断是否有安全管理器,并根据是否有安全管理器做出处理,但是都是会走到doResolveBeanClass方法,走进去
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
// 获取该工厂的加载bean用的类加载器
ClassLoader beanClassLoader = getBeanClassLoader();
// 初始化动态类加载器为该工厂的加载bean用的类加载器,如果该工厂有
// 临时类加载器器时,该动态类加载器就是该工厂的临时类加载器
ClassLoader dynamicLoader = beanClassLoader;
// 表示mdb的配置的bean类名需要重新被dynameicLoader加载的标记,默认不需要
boolean freshResolve = false;
//如果有传入要匹配的类型
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
// 仅进行类型检查时(即尚未创建实际实例),请使用指定的临时类加载器
// 获取该工厂的临时类加载器,该临时类加载器专门用于类型匹配
ClassLoader tempClassLoader = getTempClassLoader();
// 如果成功获取到临时类加载器
if (tempClassLoader != null) {
// 以该工厂的临时类加载器作为动态类加载器
dynamicLoader = tempClassLoader;
// 标记mdb的配置的bean类名需要重新被dynameicLoader加载
freshResolve = true;
// DecoratingClassLoader:装饰ClassLoader的基类,提供对排除的包和类的通用处理
// 如果临时类加载器是DecoratingClassLoader的基类
if (tempClassLoader instanceof DecoratingClassLoader) {
// 将临时类加载器强转为DecoratingClassLoader实例
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
// 对要匹配的类型进行在装饰类加载器中的排除,以交由父ClassLoader以常规方式处理
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
// 从mbd中获取配置的bean类名
String className = mbd.getBeanClassName();
// 如果能成功获得配置的bean类名
if (className != null) {
//评估benaDefinition中包含的className,如果className是可解析表达式,会对其进行解析,否则直接返回className:
Object evaluated = evaluateBeanDefinitionString(className, mbd);
// 判断className是否等于计算出的表达式的结果,如果不等于,那么判断evaluated的类型
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
// 如果evaluated属于Class实例
if (evaluated instanceof Class) {
// 强转evaluatedw为Class对象并返回出去
return (Class<?>) evaluated;
}
// 如果evaluated属于String实例
else if (evaluated instanceof String) {
// 将evaluated作为className的值
className = (String) evaluated;
// 标记mdb的配置的bean类名需要重新被dynameicLoader加载
freshResolve = true;
}
else {
// 抛出非法状态异常:无效的类名表达式结果:evaluated
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
// 如果mdb的配置的bean类名需要重新被dynameicLoader加载
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
// 当使用临时类加载器进行解析时,请尽早退出以避免将已解析的类存储在BeanDefinition中
// 如果动态类加载器不为null
if (dynamicLoader != null) {
try {
// 使用dynamicLoader加载className对应的类型,并返回加载成功的Class对象
return dynamicLoader.loadClass(className);
}
// 捕捉未找到类异常,
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
// 使用classLoader加载name对应的Class对象,该方式是Spring用于代替Class.forName()的方法,支持返回原始的类实例(如'int')
// 和数组类名 (如'String[]')。此外,它还能够以Java source样式解析内部类名(如:'java.lang.Thread.State'
// 而不是'java.lang.Thread$State')
return ClassUtils.forName(className, dynamicLoader);
}
}
// Resolve regularly, caching the result in the BeanDefinition...
// 定期解析,将结果缓存在BeanDefinition中...
// 使用classLoader加载当前BeanDefinitiond对象所配置的Bean类名的Class对象(每次调用都会重新加载,可通过
// AbstractBeanDefinition#getBeanClass 获取缓存)
return mbd.resolveBeanClass(beanClassLoader);
}
// 获取该工厂的加载bean用的类加载器 ClassLoader beanClassLoader = getBeanClassLoader(); // 初始化动态类加载器为该工厂的加载bean用的类加载器,如果该工厂有 // 临时类加载器器时,该动态类加载器就是该工厂的临时类加载器 ClassLoader dynamicLoader = beanClassLoader; // 表示mdb的配置的bean类名需要重新被dynameicLoader加载的标记,默认不需要 boolean freshResolve = false; //如果有传入要匹配的类型 if (!ObjectUtils.isEmpty(typesToMatch)) { // When just doing type checks (i.e. not creating an actual instance yet), // use the specified temporary class loader (e.g. in a weaving scenario). // 仅进行类型检查时(即尚未创建实际实例),请使用指定的临时类加载器 // 获取该工厂的临时类加载器,该临时类加载器专门用于类型匹配 ClassLoader tempClassLoader = getTempClassLoader(); // 如果成功获取到临时类加载器 if (tempClassLoader != null)//到这为空,不进入
------------
// 从mbd中获取配置的bean类名 String className = mbd.getBeanClassName(); // 如果能成功获得配置的bean类名 if (className != null) { //评估benaDefinition中包含的className,evaluateBeanDefinitionString(className, mbd);方法中如果className是可解析表达式,会对其进行解析返回string,否则直接返回className: Object evaluated = evaluateBeanDefinitionString(className, mbd); if (!className.equals(evaluated)) //该方法是看解析出来的evaluated与className是否相等,如果不相等则进行类型和string两个方面的处理。这里为false不进入 if (freshResolve)//上面解析的ClassName的数据的代码中将这个字段设置为true,说明如果className这个参数变了,这里也要进去操作。也就是加载className对应的类。为false不进入 return mbd.resolveBeanClass(beanClassLoader);点进去 创建className对应的对象
@Nullable
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
// 获取className
String className = getBeanClassName();
if (className == null) {
return null;
}
// 获取当前className创建对应的Class对象
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
this.beanClass = resolvedClass;
return resolvedClass;
}
可以看到调用ClassUtils.forName(className, classLoader);方法,返回了Class.到此,Class<?> resolvedClass = resolveBeanClass(mbd, beanName);执行完成
回到原来的creatBean方法
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 进行条件筛选,重新赋值RootBeanDefinition,并设置BeanClass属性
//resolvedClass != null:确定已经成功将BeanDefinition中指定的类名转换成了Class对象。这意味着Spring已经能够确切知道要创建哪个类的实例。
//!mbd.hasBeanClass():表示当前的BeanDefinition并没有直接与一个Class对象关联起来,换句话说,虽然我们可能知道了类的名称,但BeanDefinition还没有更新为具体的类实例。
//mbd.getBeanClassName() != null:确保BeanDefinition中确实存有类名存在。这是基本的前提,有了具体的类名才能进一步进行类的加载和解析。
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 重新创建一个RootBeanDefinition对象
mbdToUse = new RootBeanDefinition(mbd);
// 设置BeanClass属性值
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 验证及准备覆盖的方法,lookup-method replace-method,当需要创建的bean对象中包含了lookup-method和replace-method标签的时候,会产生覆盖操作
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
接着往下走
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null)
因为mbd.hasBeanClass()==true,所以不进去
继续往下走
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
点进prepareMethodOverrides();方法
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exist and determine their overloaded status.
if (hasMethodOverrides()) {
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
public boolean hasMethodOverrides() {
return !this.methodOverrides.isEmpty();
}
可以看到,查看methodOverrides集合里是否有值,也就是查看是否有重写的方法
如果想在单例模式下引用原型模式的bean,怎么办?
需要引用lookup-method方法来解决这个问题
前面走了一大堆,有注释