文章目录
直接打开AbstractBeanFactory的doGetBean
方法:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 先将方法传入的name转换成容器真实的beanName // 之前可以通过三种形式获取beanName // 一个是原始的beanName,一个是加了&的,一个是别名 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); // 加果先前已经创建过单例Bean的实例,并且调用的getBean方法传入的参数为空,则执行理面的逻辑 // args之所以要求为空是因为如果有args,则需要做进一步赋值,因此无法直接返回 if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { // 如果Bean还在创建中,则说明是循环引用 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,直接返回,如果是FactoryBean,则返回他的getObject 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 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); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. 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); } } } // Create bean instance. // 如果BeanDefinition为单例 if (mbd.isSingleton()) { // 这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象 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(); 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; } } // 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; }
第一行先将方法传入的name转换成容器真实的beanName,回顾之前,可以通过三种形式获取beanName,一个是原始的beanName,一个是加了&的,一个是别名
final String beanName = transformedBeanName(name); Object bean;
进入到transformedBeanName方法里面
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; }); }
先看看是否是以&前缀开始的,不是的话直接返回name,是的话将&全部去掉。
再进入到canonicalName方法里:
public String canonicalName(String name) { String canonicalName = name; // Handle aliasing... String resolvedName; do { // 根据别名获取真正的beanName,传入beanName就啥都获取不到 resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName; }
如果能在map里找到真名,则证明传入的是别名,为了防止是别名的别名,这里有一个递归操作直到找不到,此时为真名
回到doGetBean,获取到beanName之后就尝试去缓存获得Bean实例
Object sharedInstance = getSingleton(beanName);
进入方法里
public Object getSingleton(String beanName) { return getSingleton(beanName, true); }
第二个参数控制是否允许非延迟加载,true表示允许立即加载
protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 尝试从一级缓存里面获取完备的Bean Object singletonObject = this.singletonObjects.get(beanName); // 如果完备的单例还没有创建出来,创建中的Bean的名字会被保存在singletonsCurrentlyInCreation中 // 因此看看是否正在创建 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 尝试给一级缓存对象加锁,因为接下来就要对缓存对象操作了 synchronized (this.singletonObjects) { // 尝试从二级缓存earlySingletonObjects这个存储还没进行属性添加操作的Bean实例缓存中获取 singletonObject = this.earlySingletonObjects.get(beanName); // 如果还没有获取到并且第二个参数为true,为true则表示bean允许被循环引用 if (singletonObject == null && allowEarlyReference) { // 从三级缓存singletonFactories这个ObjectFactory实例的缓存里尝试获取创建此Bean的单例工厂实例 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); // 如果获取到工厂实例 if (singletonFactory != null) { // 调用单例工厂的getObject方法返回对象实例 singletonObject = singletonFactory.getObject(); // 将实例放入二级缓存里 this.earlySingletonObjects.put(beanName, singletonObject); // 从三级缓存里移除 this.singletonFactories.remove(beanName); } } } } return singletonObject; }
该方法在DefaultSingletonBeanRegistry
类里,负责对容器创建出来的单例进行注册,从一个map (singletonObjects)中尝试获取key为beanName的单例实例,其中singletonObjects就是一级缓存。
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName))
保证从一级缓存里没有获取到相关实例,并且该实例一定是当前正在创建的实例
public boolean isSingletonCurrentlyInCreation(String beanName) { return this.singletonsCurrentlyInCreation.contains(beanName); }
isSingletonCurrentlyInCreation方法会去查询一个set,看看正在创建的单例bean名单里是否有beanName,如果此时bean是单例的且正在创建,则会给一级缓存加一个同步锁,之后再操作另外两层缓存。
为了提高性能,二级缓存earlySingletonObjects和三级缓存singletonFactories都是HashMap,因为前面已经对一级缓存加了锁,所以是安全的。
首先尝试从二级缓存里获取Bean实例
singletonObject = this.earlySingletonObjects.get(beanName);
二级缓存里存的是还没有实例化的Bean(没执行populate)
之后又可能从三级缓存singletonFactories里尝试获取,这里存储的是Bean对应的ObjectFactory实例(工厂),后续可以通过getObject()来创建Bean的实例,由于Bean实例的属性可能还没有注入,所以先将其放入二级缓存里,然后从三级缓存里清除(保证三级缓存里只有一级保存Bean实例,避免重复创建Bean实例打破单例),之所以没有注入的Bean也要返回的原因是为了打破循环依赖问题。
回到doGetBean,
如果先前已经创建过单例Bean的实例,并且调用的getBean方法传入的参数为空,则执行理面的逻辑,args之所以要求为空是因为,如果有args,则需要做进一步赋值,因此无法直接返回。
无论是否有循环引用,最终都是要调用getObjectForBeanInstance返回Bean实例,但由于我们可能获取到的是工厂而非实例,所以还可能要多一步由工厂创建bean实例的步骤。
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. if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } // 如果name是以&开头的但是不是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. // 如果是一个普通的Bean,则直接返回 if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } // FactoryBean创建出bean实例返回 Object object = null; if (mbd != null) { mbd.isFactoryBean = true; } else { // 单例模式下,FactoryBean仅会创建一个Bean实例 // 因此需要优先从缓存获取,这里的缓存不是前面的三级缓存,这个是缓存工厂创建出来的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)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
jvm里面通过Synthetic来标识是由自己的机制生成的类,用在这里标识这是Spring内部生成的Bean实例,不允许第三方改动。
进入到getObjectFromFactoryBean方法:
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // 加果需要在工厂模式下维持单例的话 if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // 又见双重检查锁机制,尝试再从缓存中获取,防止多线程下可能有别的线程已完成该单例Bean的创建 Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // 调用工厂方法,创建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) // 看看此时是否有别的线程先人一步创建好了Bean实例,如果是,则使用最先创建出来的以保证单例 // 之所以这样做是因为factoryBean是用户自定义的,就有可能是异步模式的,即getObject可能是异步的 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { // 如果是 Synthetic 的就不能使用后置处理器服务了 if (shouldPostProcess) { // 该Bean实例是否已经有别的线程在尝试创建,但是还没有进行后置处理 if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } // 后置处理完成前,先加入缓存里锁定起来 beforeSingletonCreation(beanName); try { // 触发BeanPostProcessor,第三方框架可以在此用AOP来包装Bean实例 object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { // 创建完成后,从缓存锁定的名字里清除 afterSingletonCreation(beanName); } } if (containsSingleton(beanName)) { // 将其放入缓存,证明单例已经创建完成了 this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } 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; } }
先确保factory创建出来的是单例,如果是就先上锁,这里用到了双重锁检查机制,尝试再去factoryBeanObjectCache缓存里获取一遍,防止多线程下可能有别的线程已完成该单例Bean的创建
回到doGetBean,if块里的代码执行完了之后就会跳过else的代码块,然后再经过一系列检查之后就返回bean实例了