Spring源码浅析之bean实例的创建过程

五陵年少金市东,银鞍白马渡春风。这篇文章主要讲述Spring源码浅析之bean实例的创建过程相关的知识,希望能为你提供帮助。
@TOC
在之前的文章内容中,简单介绍了bean定义的加载过程,下面这篇的主要内容就是bean实例的创建过程。
bean实例的创建方式

ApplicationContext context = new ClassPathXmlApplicationContext("application.xml"); context.getBean("beanDemo");

首先看到上面的代码,使用了getBean方法,那么创建bean的入口是不是在getBean里面呢?
通过之前的内容,可以知道,单例bean可以提前实例化,因为能够提高使用时的效率。原型bean,即多例bean则是在getBean的时候进行实例化的。而且单例bean和原型bean的实例化过程是没有区别的,都是通过getBean方法,在启动时提前实例化也是使用的getBean方法。
bean实例创建以及配置的方式如下:
Spring源码浅析之bean实例的创建过程

文章图片

  • 构造方法的方式
通过构造函数创建实例有两种方式,一种是无参构造函数,一种是有参构造函数
下面是无参构造函数的配置方式:
public class ConstructorBean {public ConstructorBean() { System.out.println("无参构造函数......"); } }

< bean id="constructorBean" class="edu.demo.spring.instantiate.ConstructorBean" />

下面是有参构造函数的配置方式:
public class ConstructorBean {public ConstructorBean(String name, int age) { System.out.println("带参构造函数......"); System.out.println(name + "_" + age); } }

< bean id="constructorBean" class="edu.demo.spring.instantiate.ConstructorBean"> < constructor-arg index="0" value="https://www.songbingjia.com/android/翠花" /> < constructor-arg index="1" value="https://www.songbingjia.com/android/18" /> < /bean>

输出结果如下:
Spring源码浅析之bean实例的创建过程

文章图片

  • 静态工厂方法
    public class InstantiateFactory {public static String getStaticFactoryMethod() { return "静态工厂方法创建bean......"; } }

    < bean id="boyService" class="edu.demo.spring.instantiate.InstantiateFactory" factory-method="getStaticFactoryMethod" > < !--< property name="" ref=""> < /property> --> < /bean>

  • 非静态工厂方法
    public class InstantiateFactory {public String getMemberFactoryMethod(String name) { return "非静态工厂方法创建bean......"; } }

    < bean id="instantiateFactory" class="edu.demo.spring.instantiate.InstantiateFactory" />

< bean id=" grilService" factory-bean=" instantiateFactory"
factory-method=" getMemberFactoryMethod" >
< !--< constructor-arg index=" 0" value=https://www.songbingjia.com/android/" 你好" /> -->
< /bean>
- 指定工厂方法需要继承FactoryBean接口: ```java public class BoyFactoryBean implements FactoryBean< Boy> {@Override public Boy getObject() throws Exception { return new Lad("niulang"); }@Override public Class< ?> getObjectType() { return Boy.class; } }

< bean name="boyService2" class="edu.demo.spring.instantiate.BoyFactoryBean"> < /bean>

如果要获取BoyFactoryBean自身,需要加上" & " 前缀,否则返回的是getObject中的bean,这是由FactoryBean创建的bean实例
Object lsfb2 = context.getBean("boyService2"); System.out.println(lsfb2); Object lsfb4 = context.getBean("& boyService2"); System.out.println(lsfb4); BoyFactoryBean lsfb = (BoyFactoryBean) context.getBean("& boyService2"); System.out.println(lsfb); System.out.println(lsfb.getObject());

分别输出如下:
Spring源码浅析之bean实例的创建过程

文章图片

实例化bean的流程从AbstractApplicationContext类中的refresh()方法看起,这里有个步骤,是提前实例化一些单例bean:
//完成bean工厂的初始化,初始化所有非懒加载的单例bean finishBeanFactoryInitialization(beanFactory);

点进去查看具体的实现:
/** * Finish the initialization of this context\'s bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. //实例化类型转换服务 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) & & beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); }// Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. //确保beanFacotory持有嵌入值的解析器 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); }// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. // 提前实例化LoadTimeWeaverAware beans String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); }// Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. // 冻结配置,要进行实例化了,bean定义信息就不能进行更改了 beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. // 实例化单例bean beanFactory.preInstantiateSingletons(); }

然后会进入preInstantiateSingletons方法:
/** 按照注册顺序存放的bean定义名称集合 */ private volatile List< String> beanDefinitionNames = new ArrayList< > (256);

// Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. //获取到所有的bean定义名称 List< String> beanNames = new ArrayList< > (this.beanDefinitionNames);

根据上面的代码可以看到,这个方法刚一进来,就获取所有的bean定义名称,这个bean定义的list使用了volatile关键字进行修饰,关于volatile不清楚的可以看下之前线程方面的文章。
// Trigger initialization of all non-lazy singleton beans... //触发所有非懒加载单例bean的初始化 for (String beanName : beanNames) { //获取合并之后的bean定义信息 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //如果bean定义不是抽象的,并且是单例的,不是懒加载的,就继续执行 if (!bd.isAbstract() & & bd.isSingleton() & & !bd.isLazyInit()) { //如果是工厂bean就继续执行,否则直接执行getBean方法 if (isFactoryBean(beanName)) { //获取bean,这里的bean是一个工厂bean Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean< ?> factory = (FactoryBean< ?> ) bean; //判断是不是急需实例化的 boolean isEagerInit; if (System.getSecurityManager() != null & & factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction< Boolean> ) ((SmartFactoryBean< ?> ) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean & & ((SmartFactoryBean< ?> ) factory).isEagerInit()); } //如果这个bean急需实例化,就调用getBean方法 if (isEagerInit) { getBean(beanName); } } } else { //获取普通bean getBean(beanName); } } }

FactoryBean是什么,上面已经有了简单的使用,FactoryBean虽然也是一个bean,但是它是一个可以生产bean的bean。如果直接使用getBean获取的是它生产的bean,所以需要使用getBean(& + beanName)才能获取这个工厂bean。
doGetBean方法介绍
protected < T> T doGetBean( String name, @Nullable Class< T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {}

这里传过来了四个参数,第一个参数name就是bean定义的名称,requiredType是bean所需要的类型,args是显式传过来的参数,typeCheckOnly是否类型检查。
args指的就是下面代码中的参数:
ConstructorBean constructorBean = (ConstructorBean) context.getBean("constructorBean", new Object[]{1,2,3});

使用刚刚上面的示例,然后debug到doGetBean方法可以看到:
Spring源码浅析之bean实例的创建过程

文章图片

进入方法的第一步就执行了transformedBeanName方法:
String beanName = transformedBeanName(name); Object bean;

这个transformedBeanName方法就是获取到标准的bean定义名称,什么是标准的bean定义名称呢?因为在配置bean定义的时候,可以给这个bean定义一些别名。
当使用getBean(" 别名" )也是可以获取到这个bean定义的。主要的原因就是底层使用了aliasMap,这个aliasMap的key值就是别名,value值就是真正的bean定义名称。
/** Map from alias to canonical name. */ private final Map< String, String> aliasMap = new ConcurrentHashMap< > (16);

/** * Return the bean name, stripping out the factory dereference prefix if necessary, * and resolving aliases to canonical names. * @param name the user-specified name * @return the transformed bean name */ protected String transformedBeanName(String name) { return canonicalName(BeanFactoryUtils.transformedBeanName(name)); }

这里又调用了BeanFactoryUtils.transformedBeanName和canonicalName两个方法:
/** * 返回bean名称,必要时去掉工厂解引用前缀 * @param name the name of the bean * @return the transformed name * @see BeanFactory#FACTORY_BEAN_PREFIX */ public static String transformedBeanName(String name) { Assert.notNull(name, "\'name\' must not be null"); //如果bean名称不包含& 前缀,就直接返回 if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) { return name; } //去除bean名称的解引用前缀,也就是& 前缀 return transformedBeanNameCache.computeIfAbsent(name, beanName -> { do { beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()); } while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); return beanName; }); }

/** * 这个方法的作用,就是获取到真正的bean名称 * @param name the user-specified name * @return the transformed name */ 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; }

canonicalName里面使用了do...while循环来获取真正的bean名称,下面来个小例子看一下:
< bean id="constructorBean" name="bean1,bean2,bean3,bean4" class="edu.demo.spring.instantiate.ConstructorBean"> < constructor-arg index="0" value="https://www.songbingjia.com/android/翠花" /> < constructor-arg index="1" value="https://www.songbingjia.com/android/18" /> < /bean> < alias name="bean2" alias="a"/>

ConstructorBean constructorBean = (ConstructorBean) context.getBean("a");

上面给constructorBean配置了4个别名bean1,bean2,bean3,bean4,而且给别名bean2又配置了一个别名a,也就是别名的别名。
debug后可以看到,这里传过来的就是别名bean2的别名a:
Spring源码浅析之bean实例的创建过程

文章图片

下面的图中,展示了bean定义别名的aliasMap:
Spring源码浅析之bean实例的创建过程

文章图片

现在清楚这里为啥使用do...while循环来获取标准的bean名称了吗,就是因为bean定义的别名,也可以有别名。当resolvedName为空,也就是说没有别名了,就会跳出循环,获取到真正的bean名称了。
接下来使用if...else分成了两个部分,先来看下第一部分:
// Eagerly check singleton cache for manually registered singletons. //从缓存中获取已经实例化的单例bean Object sharedInstance = getSingleton(beanName); //如果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 + "\'"); } } //这里,是判断这个bean是不是FactoryBean,如果是FactoryBean,那么就要从FactoryBean中创建一个实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }

下面先看下getSingleton这个方法
/** 单例bean的缓存 */ private final Map< String, Object> singletonObjects = new ConcurrentHashMap< > (256); /** 单例工厂的缓存 */ private final Map< String, ObjectFactory< ?> > singletonFactories = new HashMap< > (16); /** 预加载的单例bean的缓存 */ private final Map< String, Object> earlySingletonObjects = new HashMap< > (16); @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { //首先从单例bean的缓存中获取bean实例 Object singletonObject = this.singletonObjects.get(beanName); //如果没有获取到并且这个bean正在创建中就执行下面的内容 if (singletonObject == null & & isSingletonCurrentlyInCreation(beanName)) { //加锁 synchronized (this.singletonObjects) { //从预加载的单例bean的缓存中获取bean实例 singletonObject = this.earlySingletonObjects.get(beanName); 、 //如果还是没有获取到,而且是需要创建早期的引用的 if (singletonObject == null & & allowEarlyReference) { //从beanName中获取单例工厂 ObjectFactory< ?> singletonFactory = this.singletonFactories.get(beanName); //如果工厂不为空 if (singletonFactory != null) { //获取bean singletonObject = singletonFactory.getObject(); //放入预加载的单例bean的缓存中 this.earlySingletonObjects.put(beanName, singletonObject); //把bean从singletonFactories中移除, //因为已经在上面加入到earlySingletonObjects了,所以singletonFactories就不需要了 this.singletonFactories.remove(beanName); } } } } return singletonObject; }

如果上面的方式没有获取到bean实例,那么就走下面的else方法:
// Fail if we\'re already creating this bean instance: // We\'re assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }

首先这里,是判断原型bean是否已经在构建中了,来检测循环依赖的,比如创建bean1的时候需要依赖bean2,而创建bean2的过程中又依赖bean1,那么这样就会抛出异常。
下面的代码,就是判断父工厂的:
// Check if bean definition exists in this factory. //首先,获取父工厂 BeanFactory parentBeanFactory = getParentBeanFactory(); //如果父工厂不为空,并且本地又不包含这个bean定义,那就从父工厂中获取 if (parentBeanFactory != null & & !containsBeanDefinition(beanName)) { // Not found -> check parent. //这一步就是还原原来的bean名称,因为有factoryBean的存在, //上面把它的前缀去掉,这里要加回来 String nameToLookup = originalBeanName(name); //下面就是通过父类去创建bean实例 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); } }

从上面的代码可以看到,parentBeanFactory.getBean,这里又使用了getBean方法,可见也是递归调用。
if (!typeCheckOnly) { markBeanAsCreated(beanName); }

上面的代码,是判断,如果这里不仅仅是做类型检查,那这里就记录一下,记录该bean已经被创建了。下面是markBeanAsCreated方法:
/** Map from bean name to merged RootBeanDefinition. */ private final Map< String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap< > (256); /** Names of beans that have already been created at least once. */ private final Set< String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap< > (256)); protected void markBeanAsCreated(String beanName) { //首先,判断已经创建的bean集合中是否包含该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定义清除掉,让bean定义重新合并, //为了防止这个bean定义发生了变化 clearMergedBeanDefinition(beanName); //把beanName加入到已经创建的集合中 this.alreadyCreated.add(beanName); } } } }

然后再次进入下面的代码:
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. //获取依赖的bean 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 + "\'"); } //注册依赖的bean registerDependentBean(dep, beanName); try { //获取到依赖的bean getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "\'" + beanName + "\' depends on missing bean \'" + dep + "\'", ex); } } }

这里先是获取合并后的bean定义,然后检测该bean是否是抽象的,如果是的话,就会抛出异常,这个判断在checkMergedBeanDefinition方法内。
然后是看这个bean是否依赖了其他bean,如果有依赖,就把依赖的bean注册到一个依赖的map中,然后调用getBean方法,先把依赖的bean实例化。
最后,如果上面都判断结束,还是没有获取到bean实例的话,就执行下面的代码来创建bean实例:
// Create bean instance. // Scope的处理:单例、原型、其他 //判断是否单例 if (mbd.isSingleton()) { //获取单例bean,如果获取不到就进行创建,然后缓存到单例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的处理 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //原型bean的处理 else if (mbd.isPrototype()) { // It\'s a prototype -> create a new instance. Object prototypeInstance = null; try { //多例bean的循环依赖检查,并且做记录 beforePrototypeCreation(beanName); //创建bean prototypeInstance = createBean(beanName, mbd, args); } finally { //释放循环依赖检查的记录 afterPrototypeCreation(beanName); } //进行工厂bean的处理 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //其他范围bean的处理 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 { //创建bean return createBean(beanName, mbd, args); } finally { //释放循环依赖检查的记录 afterPrototypeCreation(beanName); } }); //进行工厂bean的处理 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); } }

上面的创建,分成了三个部分,分别是单例、多例和其他范围的bean,大致的处理过程是一样的,都调用了createBean方法进行创建。
getSingleton方法下面来看下单例bean的getSingleton方法:
/** * Return the (raw) singleton object registered under the given name, * creating and registering a new one if none registered yet. * @param beanName the name of the bean * @param singletonFactory the ObjectFactory to lazily create the singleton * with, if necessary * @return the registered singleton object */ public Object getSingleton(String beanName, ObjectFactory< ?> singletonFactory) {}

这个方法用来获取单例bean,而且会调用创建bean的方法。
synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); }

首先进行了加锁,然后从singletonObjects中获取单例bean,singletonObjects上面已经说过,里面存放了已经实例化的单例bean集合,这里先从singletonObjects获取,如果获取不到,再进行创建。
/** Flag that indicates whether we\'re currently within destroySingletons. */ private boolean singletonsCurrentlyInDestruction = false; /** Collection of suppressed Exceptions, available for associating related causes. */ @Nullable private Set< Exception> suppressedExceptions;

//如果获取不到该单例bean,那么就进行创建 if (singletonObject == null) { //判断该单例bean是否正在销毁,是的话就抛异常 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创建之前的处理,也是进行记录 beforeSingletonCreation(beanName); //是否新创建的单例bean boolean newSingleton = false; //记录在创建过程中产生的异常,可能是的,这个我猜的,哈哈 boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet< > (); } }

然后看下beforeSingletonCreation这个方法
/** Names of beans that are currently in creation. */ private final Set< String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap< > (16)); /** Names of beans currently excluded from in creation checks. */ private final Set< String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap< > (16)); protected void beforeSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) & & !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } }

进行了判断和添加,inCreationCheckExclusions是排除的bean名称集合,也就是说这个bean不会被创建。singletonsCurrentlyInCreation记录当前正在创建的bean名称。
下面就是进行创建的代码:
try { //singletonFactory就是执行上面的创建bean代码 singletonObject = singletonFactory.getObject(); //创建完成后,标志为新的单例bean newSingleton = true; }

然后下面的代码就是进行一些缓存:
finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } //移除记录 afterSingletonCreation(beanName); } //如果是新的单例bean,就进行一些缓存 if (newSingleton) { addSingleton(beanName, singletonObject); }

看下afterSingletonCreation方法,就是把当前的bean从正在创建的集合中移除掉
protected void afterSingletonCreation(String beanName) { if (!this.inCreationCheckExclusions.contains(beanName) & & !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton \'" + beanName + "\' isn\'t currently in creation"); } }

然后下面就是缓存的方法了:
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); } }

这个方法就比较简单了,把已经实例化的单例bean加入到singletonObjects集合,因为已经实例化了,所以从singletonFactories和earlySingletonObjects中移除了,而且还加入到了registeredSingletons集合中。
原型bean下面来看下原型bean的处理:
/** Names of beans that are currently in creation. */ private final ThreadLocal< Object> prototypesCurrentlyInCreation = new NamedThreadLocal< > ("Prototype beans currently in creation"); protected void beforePrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal == null) { this.prototypesCurrentlyInCreation.set(beanName); } else if (curVal instanceof String) { Set< String> beanNameSet = new HashSet< > (2); beanNameSet.add((String) curVal); beanNameSet.add(beanName); this.prototypesCurrentlyInCreation.set(beanNameSet); } else { Set< String> beanNameSet = (Set< String> ) curVal; beanNameSet.add(beanName); } }

protected void afterPrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal instanceof String) { this.prototypesCurrentlyInCreation.remove(); } else if (curVal instanceof Set) { Set< String> beanNameSet = (Set< String> ) curVal; beanNameSet.remove(beanName); if (beanNameSet.isEmpty()) { this.prototypesCurrentlyInCreation.remove(); } } }

从上面的源码,可以看到,prototypesCurrentlyInCreation使用到了ThreadLocal,可以避免线程重复创建bean,afterPrototypeCreation是把这个标志给移除掉。而scope和原型bean这块的处理是一样的。
getObjectForBeanInstance方法最后呢,还有一个方法没有看,下面就来看下getObjectForBeanInstance这个方法吧。
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {}

这里传来了四个参数,beanInstance是bean实例,name是原始的bean名称,也就是可能包含& 前缀,beanName是标准的bean名称,mbd是合并之后的bean定义信息。
/** Package-visible field for caching if the bean is a factory bean. */ @Nullable volatile Boolean isFactoryBean;

//判断是不是工厂bean if (BeanFactoryUtils.isFactoryDereference(name)) { //如果是NullBean,直接返回 if (beanInstance instanceof NullBean) { return beanInstance; } //如果不是FactoryBean类型,直接抛出异常 //是工厂bean,但是不是FactoryBean类型 if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } //设置isFactoryBean标志,标志该bean是工厂bean if (mbd != null) { mbd.isFactoryBean = true; } //返回bean实例 return beanInstance; }

判断是不是工厂bean的方法,比较简单,判断是不是以& 开头的:
public static boolean isFactoryDereference(@Nullable String name) { return (name != null & & name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); }

如果当前bean实例不是FactoryBean类型,直接返回
// 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; }

如果上面都没有获取到bean实例,则执行下面的代码:
/** Cache of singleton objects created by FactoryBeans: FactoryBean name to object. */ private final Map< String, Object> factoryBeanObjectCache = new ConcurrentHashMap< > (16);

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. //如果bean定义为空,且beanDefinitionMap中包含该bean名称,则获取合并后的bean定义 if (mbd == null & & containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } //是否是用户自定义的bean boolean synthetic = (mbd != null & & mbd.isSynthetic()); //从FactoryBean中获取bean object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object;

getCachedObjectForFactoryBean方法比较简单,直接从缓存的map中获取即可:
@Nullable protected Object getCachedObjectForFactoryBean(String beanName) { return this.factoryBeanObjectCache.get(beanName); }

再然后就是getObjectFromFactoryBean,从FactoryBean中来获取对象:
protected Object getObjectFromFactoryBean(FactoryBean< ?> factory, String beanName, boolean shouldPostProcess)

这里传过来三个参数,factory就是上面传过来的factoryBean,beanName就是配置里面定义的bean名称,shouldPostProcess的意思是:是否允许bean进行后置处理。
if (factory.isSingleton() & & containsSingleton(beanName)) { synchronized (getSingletonMutex()) { } }

首先上来就是判断,这个factory是不是单例的,单例bean的集合中是否包含这个bean名称,如果都满足就执行下面的代码。
/** 由FactoryBean创建的单例对象的缓存:对象的FactoryBean名称 */ private final Map< String, Object> factoryBeanObjectCache = new ConcurrentHashMap< > (16);

//首先从缓存中获取 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) //再次从缓存中获取,由于循环引用可能导致这个bean已经在缓存中了 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); //获取到了就直接赋值 if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { //当前bean正在创建直接返回,暂时不做后置处理 if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } //循环依赖检查,做记录 beforeSingletonCreation(beanName); try { //对这个bean做后置处理 object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean\'s singleton object failed", ex); } finally { //循环依赖检查,移除 afterSingletonCreation(beanName); } } //当前bean是否在单例bean的集合中,如果是的就缓存 if (containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object); } } } //返回bean实例 return object;

再然后就是else里面的处理,代码量较少,if里面已经有相同的代码了。
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方法:
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 { //这里,直接调用了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. 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实例。
创建实例流程图下面,根据上面的源码内容,做一个简单的流程图,方便进行总结和查看:
Spring源码浅析之bean实例的创建过程

文章图片

【Spring源码浅析之bean实例的创建过程】到此,getBean相关的内容已经介绍完毕了,下面就是真正创建bean实例的过程了。文章旨在记录学习内容和分享,如有不足还请见谅,文章中若有错误的地方,还望大佬不吝赐教,及时指正,共同学习,共同进步,互勉!

    推荐阅读