Spring5.1.x版本,使用注解扫描的方式
接上一篇Spring IOC 源码解析之refresh(二),继续分析getBean方法。
文章目录
该方法就是用来获取bean的,如果不存在,就会进行创建。
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
/**
* 返回bean实例,若没有则先实例化
* @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、获取一个正规的beanName,处理两种情况,一个是前面说的 FactoryBean(前面带 ‘&’),
// 一个是别名问题,因为这个方法是 getBean,获取 Bean 用的,你要是传一个别名进来,是完全可以的
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 2、从单例map中尝试获取bean,看是否已经存在
// (如果存在,那该实例可能是一个完整的bean,也可能是已经实例化,但还没初始化的bean)
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 + "'");
}
}
// 3、如果是普通 Bean 的话,直接返回 sharedInstance,
// 如果是 FactoryBean 的话,返回它创建的那个实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 进入这里表示bean实例还不存在,即将要去创建
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 4、针对prototype的bean,表明有循环依赖,prototype不能有循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// 5、检查一下这个 BeanDefinition 在容器中是否存在,如果父容器存在并且BeanDefinition
// 在当前容器不存在,则去父容器中查找
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) {
// 6、将bean标记为已创建(或将要创建)
markBeanAsCreated(beanName);
}
try {
// 7、由于在上一步可能清除了beanName的合并bean定义,所以这里重新获取合并bean定义
// 并检查该合并bean定义
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 8、先初始化要依赖的Bean,这里指的是depends-on 中定义的依赖,不是作为属性的依赖
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// depends-on 不允许循环依赖,因为depends-on就是来决定实例化顺序的,
// 循环依赖了就不知道先实例化谁
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 为给定的bean注册一个从属bean,要在给定的bean被销毁之前将其销毁
registerDependentBean(dep, beanName);
try {
// 先初始化依赖项
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 9、创建单例
// 再从单例缓存中获取实例,若没获取到,则从ObjectFactory创建单例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 的话,直接返回 sharedInstance,如果是 FactoryBean 的话,返回它创建的那个实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 10、创建prototype实例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 创建之前先将bean名称放到当前线程的缓存中,这里可以看出prototype不支持循环依赖
beforePrototypeCreation(beanName);
// prototype就是直接调用createBean创建
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 跟上面对应
afterPrototypeCreation(beanName);
}
// 如果是普通 Bean 的话,直接返回 sharedInstance,如果是 FactoryBean 的话,返回它创建的那个实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 11、创建除sington和prototype其他scope的bean
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;
}
}
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名称转换为真正的名称
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
如果有&前缀,先去除前缀
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;
}
2、从单例map中尝试获取bean
public Object getSingleton(String beanName) {
// true表示允许提前暴露bean
return getSingleton(beanName, true);
}
/**
* 解决循环引用逻辑:使用构造函数创建一个 “不完整” 的 bean 实例(之所以说不完整,
* 是因为此时该 bean 实例还未初始化),并且提前曝光该 bean 实例的 ObjectFactory
*(提前曝光就是将 ObjectFactory 放到 singletonFactories 缓存),
* 通过 ObjectFactory 我们可以拿到该 bean 实例的引用,如果出现循环引用,
* 我们可以通过缓存中的 ObjectFactory 来拿到 bean 实例,从而避免出现循环引用导致的死循环。
* 这边通过缓存中的 ObjectFactory 拿到的 bean 实例虽然拿到的是 “不完整” 的 bean 实例,
* 但是由于是单例,所以后续初始化完成后,该 bean 实例的引用地址并不会变,
* 所以最终我们看到的还是完整 bean 实例
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从一级单例缓存(即最终存放bean的缓存)中尝试获取bean实例
Object singletonObject = this.singletonObjects.get(beanName);
// 1、若一级单例缓存中存在该bean则直接返回
// 2、不存在则再判断该bean是否正在创建
// 2.1、没有正在创建,则直接返回null
// 2.2、正在创建状态则再从二级缓存中判断
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 为什么会返回属性还没注入的bean实例,是为了解决循环依赖
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 从三级缓存中获取到后放到二级缓存中,删除三级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
// 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
这里之所以使用三级缓存是为了解决循环依赖。
3、从上一步获取到的对象中得到真正的bean,因为有可能是FactoryBean
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
String currentlyCreatedBean = this.currentlyCreatedBean.get();
if (currentlyCreatedBean != null) {
registerDependentBean(beanName, currentlyCreatedBean);
}
return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}
调用父类方法获取给定 bean 实例的对象,bean 实例本身或其创建的对象(如果是 FactoryBean)
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果name是以&为前缀但是beanInstance并不是FactoryBean,则抛异常
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
// 如果beanInstance不是FactoryBean(普通bean)或者name是以&为前缀(返回FactoryBean本身),
// 则直接返回beanInstance
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 走到下面说明beanInstance是FactoryBean,name不带有&前缀,
// 需要通过beanInstance创建真正的bean
Object object = null;
if (mbd == null) {
// 如果mbd为空,则从缓存中先获取FactoryBean所创建的bean
object = getCachedObjectForFactoryBean(beanName);
}
// 如果是空的就需要从FactoryBean创建
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());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 如果当前的FactoryBean是单例并且已经在单例缓存中存在
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 先从factoryBean创建的bean缓存中获取下看存不存在,已经存在就直接返回了
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 如果缓存中不存在则调用doGetObjectFromFactoryBean正在执行从
// FromFactory创建bean的逻辑
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做后置处理和放进缓存
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
// 如果beanName正在创建,则不做后置处理和缓存
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
// 对bean实例进行后置处理,执行所有已注册的BeanPostProcessor的
// postProcessAfterInitialization方法
// todo Before是在哪里调用的?
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
// 将object放进factoryBeanObjectCache缓存,下次直接就从这里面获取
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
// 不是单例,所以每次都需要调用getObject方法创建新的bean
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;
}
}
doGetObjectFromFactoryBean,真正去调用getObject创建bean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final 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 {
// 调用getObject方法
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.
// 如果FactoryBean自身还没有完全初始化,则getObject方法不允许返回空对象
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;
}
这里面就只是通过调用FactoryBean的getObject方法来创建bean。
4、针对prototype的bean
判断是否有循环依赖,prototype不能有循环依赖,如果有则抛异常。
5、检查一下这个 BeanDefinition 在容器中是否存在
如果父容器存在并且BeanDefinition在当前容器不存在,则去父容器中查找
6、将bean标记为已创建(或将要创建)
protected void markBeanAsCreated(String beanName) {
// 双重检查锁确保该bean还没被标记为已创建
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.
// 清除合并的bean定义,下次需要再重新合并,以防它的一些元数据同时发生变换
clearMergedBeanDefinition(beanName);
// 将该beanName添加进已创建名单中
this.alreadyCreated.add(beanName);
}
}
}
}
protected void clearMergedBeanDefinition(String beanName) {
this.mergedBeanDefinitions.remove(beanName);
}
7、重新获取合并bean定义并检查
由于在上一步可能清除了beanName的合并bean定义,所以这里重新获取合并bean定义,并检查该合并bean定义。
8、初始化要依赖的Bean
在创建bean之前需要先初始化它要依赖的Bean,这里指的是depends-on 中定义的依赖,不是作为属性的依赖,这里可以看出depends-on可以决定bean的创建顺序。
9、创建单例bean(重点)
根据bean定义的scope属性判断是否单例。
这里就真正开始创建单例,再从单例缓存中获取实例,若没获取到,则从ObjectFactory创建单例bean实例。
// 从单例缓存中获取实例,若没获取到,则从ObjectFactory创建单例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 的话,直接返回 sharedInstance,如果是 FactoryBean 的话,返回它创建的那个实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 用同步块包住,防止并发创建
synchronized (this.singletonObjects) {
// 如果已经在singletonObjects存在了,就直接返回
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
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 + "'");
}
// 将bean名称放进singletonsCurrentlyInCreation缓存中
// 表示该bean正在创建
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 获取到的是一个完整的并且已经初始化完成的实例
// 从上面得知getObject方法中就一句代码调用createBean方法
singletonObject = singletonFactory.getObject();
// 标记为新的单例对象
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.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 从singletonsCurrentlyInCreation缓存中将bean名称移除,
// 表示创建完成
afterSingletonCreation(beanName);
}
// 如果是新创建的bean
if (newSingleton) {
// 将bean加入到一级单例缓存中,并删除其余两个缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
其中createBean方法在下一篇Spring IOC 源码解析之createBean(四)再解析。
创建完单例后会将bean加入到一级单例缓存中,并删除其余两个缓存
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 添加到单例bean缓存中
this.singletonObjects.put(beanName, singletonObject);
// 移除另外两个缓存
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
// 添加到已注册的单例bean缓存中
this.registeredSingletons.add(beanName);
}
}
10、创建prototype实例
scope属性为prototype
// 10、创建prototype实例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 创建之前先将bean名称放到当前线程的缓存中,这里可以看出prototype不支持循环依赖
beforePrototypeCreation(beanName);
// prototype就是直接调用createBean创建
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 跟上面对应
afterPrototypeCreation(beanName);
}
// 如果是普通 Bean 的话,直接返回 sharedInstance,如果是 FactoryBean 的话,返回它创建的那个实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
11、创建除sington和prototype其他scope的bean
// 11、创建除sington和prototype其他scope的bean
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);
}
}