整体流程
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
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 + "'");
}
}
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.
// 没有设置过父BeanFactory所以该分支目前也不会走
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 if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// typeCheckOnly false
if (!typeCheckOnly) {
// 标记为已创建,并放入alreadyCreated缓冲中
markBeanAsCreated(beanName);
}
try {
// 获取bean定义
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 如果是抽象类会抛出异常 BeanIsAbstractException
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 保证bean配置的依赖都已经实例化了。<bean class="xxx" depends-on="xxxx">
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 遍历实例化依赖的bean
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);
}
}
}
// Create bean instance.
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();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
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.
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;
}
transformedBeanName
然后进入 doGetBean 方法,这里面代码很多,分成小段来看。
第一个小段:transformedBeanName 转换 bean 的名称,都给了 beanName 为啥还要转换?因为 bean 是有别名的,需要把这个别名转换成最终指向的 bean 的 beanName.
spring-beans | org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object bean;
.....
}
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
调用静态方法,这个方法还是比较容易理解的,如下所示:
spring-beans | org.springframework.beans.factory.BeanFactoryUtils#transformedBeanName
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
// 如果不是FactoryBean就直接返回。(FactoryBean的开头是&)
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 如果是FactoryBean的话,返回去掉&的名称,同时加入缓存,例如:{&hello=hello}
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
然后是 canonicalName 方法,规范化名字,利用别名缓存把别名转换成真正的名字
spring-core | org.springframework.core.SimpleAliasRegistry#canonicalName
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;
}
getSingleton
得到 bean 的名称后,从缓存中尝试获取这个bean的实例。
spring-beans | org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
@Override
@Nullable
public Object getSingleton(String beanName) {
// 参数true表示允许早期依赖
return getSingleton(beanName, true);
}
进入方法,从三个缓存中进行判断
spring-beans | org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 从单例bean缓存中查找。称为:第一级缓存,用于存放完全初始化好的bean
Object singletonObject = this.singletonObjects.get(beanName);
// 从"bean状态:创建中"的缓存中查找。
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 从早期单例bean缓存中查找。
// 称为:第二级缓存,提前曝光的单例对象的cache,存放原始的bean对象(尚未填充属性),用于解决循环依赖
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果允许引用的话
if (singletonObject == null && allowEarlyReference) {
// 同步操作
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 从singletonFactories缓存中判断。称为:第三级缓存
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 得到对象
singletonObject = singletonFactory.getObject();
// 加入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 去掉三级缓存
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
首先从 singletonObjects 里面获取实例,如果获取不到再从 earlySingleObjects 里面获取,如果还获取不到再从 singleFactories 里面获取对应的 ObjectFactory,然后利用其 getObject 方法来获取 bean 并放到 earlySingleObjects 里面,再从 singleFactories 中移除该 ObjectFactory .
代码执行流程图:
这里也是三级缓存解决循环依赖的处理办法,详情见:Spring 利用三级缓存解决循环依赖的方式!
getObjectForBeanInstance
接下来就会有两个大分支,一是从缓存中没有拿到对象,另一个是拿到了。
无论走哪个分支,最后都会调用 getObjectForBeanInstance 这个方法。因为我们得到 bean 的实例后要做的第一件事就是验证一下正确性✅ ,其实就是检测一下这个实例是不是 FactoryBean 类型的 bean,如果是就调用 getObject() 方法得到的返回值作为最终的 bean.
org.springframework.beans.factory.support.AbstractBeanFactory#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.
// 表明用户想要获取 factoryBean 实例
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 如果bean是工厂相关(名称特点:&beanName),但是 beanInstance 又不是 FactoryBean实例,异常
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.
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
} else {
// 尝试从缓存中获取bean
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)) {
// 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition
// 如果指定BeanName是子Bean的话同时会合并父类的相关属性
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否用户自定义的配置,而不是程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
流程:
- 该方法首先判断用户想要的是不是 FactoryBean ,因为 FactoryBean 的名称开头是 & 符号,并且做了些校验;
- 如果不是 FactoryBean 直接返回;
- 如果 FactoryBean 想要得到具体 bean 的话,首先尝试从缓存获取 bean;
- 如果缓存中没有的话,利用 FactoryBean 来创建 bean,创建就交给了 getObjectFromFactoryBean 方法。
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 单例已注册的bean
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;
}
// bean状态设置为创建中,加入 singletonsCurrentlyInCreation 缓存
beforeSingletonCreation(beanName);
try {
// 执行处理器.
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// bean 从 singletonsCurrentlyInCreation 缓存中移除
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
// 非单例的bean
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;
}
}
过程:
- 单例的从缓存中先判断,然后再调用方法 doGetObjectFromFactoryBean 创建,再执行各种处理器;
- 多例的直接调用方法 doGetObjectFromFactoryBean 创建,然后执行各种处理器;(以为多例的不缓存);
所以最终创建的方法是 doGetObjectFromFactoryBean
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName)
throws BeanCreationException {
Object object;
try {
// 权限验证
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 获取 bean
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
// 不接受null,为空返回 NullBean
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
过程:
- 首先做权限验证;
- 然后调用方法 getObject 创建 bean;
对于返回 null 是不允许的,包装成 NullBean。否则正常返回就行了。
缓存有对象
// 如果从缓存中拿到了实例
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 + "'");
}
}
// 注册并得到创建好的对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
从缓存中获取到了对象后,就调用 getObjectForBeanInstance 方法获取即可。
缓存无对象
缓存中没有的话,就需要进行创建对象了。
// 从缓存中没有拿到实例
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.
// 没有设置过父BeanFactory所以该分支目前也不会走
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 if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// typeCheckOnly false
if (!typeCheckOnly) {
// 标记为已创建,并放入alreadyCreated缓冲中
markBeanAsCreated(beanName);
}
try {
// 获取bean定义
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 如果是抽象类会抛出异常 BeanIsAbstractException
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 保证bean配置的依赖都已经实例化了。<bean class="xxx" depends-on="xxxx">
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 遍历实例化依赖的bean
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);
}
}
}
// Create bean instance.
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();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
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;
}
}
缓存中没有对象,这个情况很好模拟。加载一个普通的 bean 即可,比如
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"https://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="user" class="cn.lichenghao.entity.User">
<property name="name">
<value>Rod</value>
</property>
<property name="age">
<value>31</value>
</property>
</bean>
</beans>
public class App2 {
public static void main(String[] args) {
// 根据配置文件加载bean
ClassPathXmlApplicationContext classPathXmlApplicationContext
= new ClassPathXmlApplicationContext("bean.xml");
User bean = classPathXmlApplicationContext.getBean(User.class);
bean.sayHello();
}
}
默认情况下是单例,并且也没有设置过父 BeanFactory 所以前两个小分支也不会走,直接到了下面。
if (!typeCheckOnly) {
// 标记为已创建
markBeanAsCreated(beanName);
}
来到方法。
spring-beans | org.springframework.beans.factory.support.AbstractBeanFactory#markBeanAsCreated
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
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.
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
这块代码就是利用了两了缓存,alreadyCreated,mergedBeanDefinitions 。标记📌 就进入了 alreadyCreated 缓存。
这块的代码全都是为了后面的创建bean在做准备。那么也到了处理bean的最重要的环节:createBean 。