探索Spring创建Bean过程

探索Spring创建Bean过程,第1张

        Spring对于Java程序员来说,是必须要掌握的一个框架。工作中我们基本上也是使用spring来进行日常的开发。却对项目中的bean创建过程并不是很了解。我自己就属于这种情况。也在网上看过很多的视频,但是都没有将看过的知识点进行总结。导致对于源码总是一知半解的状态。本篇文章用来记录我在探索spring创建bean的源码总结。

1. 准备工作

        阅读源码,个人觉得最好的方法是DEBUG断点调试法,一步一步的看下去,最终找到自己想要的知识,在DEBUG之前就需要准备一个spring项目。可以使用idea创建一个spring boot项目,然后删除配置文件,并创建一个applicationContext.xml文件,整体结构如下图:

 启动类上的@SpringBootApplication注解删除,启动类中的main方法中通过ClassPathXmlApplicationContext来接在spring的配置文件。并创建一个自定义类User,User类提供一个无参构造函数和全参构造函数。效果如下:

启动类:

package com.edu.spring.study;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringStudyApplication {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) context.getBean("user");
        System.out.println(user);
    }
}

User类:

package com.edu.spring.study;

/**
 * @Author alen
 * @DATE 2022/5/3 14:46
 */
public class User {

    private int id;

    private String name;

    private String mobile;

    public User() {
        System.out.println("无参构造,通过我创建对象了");
    }

    public User(int id, String name, String mobile) {
        this.id = id;
        this.name = name;
        this.mobile = mobile;
        System.out.println("全参构造,通过我创建对象了");
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
}

通过从启动类的main方法开始使用debug断点调试法一步一步探索在哪里调用了构造函数创建了对象,就是在哪里打印了构造函数的输出语句。

2. 执行过程 2.1 执行启动类的main方法

通过执行main方法,可以得出:Userd对象的创建是执行ClassPathXmlApplicationContext的创建过程中创建了,并且调用的是无参构造函数创建的。效果如下:

 2.2 跟踪ClassPathXmlApplicationContext的创建

首先执行的是ClassPathXmlApplicationContext的构造函数,构造函数详细代码如下

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
    super(parent);
    this.setConfigLocations(configLocations);
    if (refresh) {
        //执行完该方法后User对象就被创建了
        this.refresh();
    }
}

2.3 阅读 this.refresh()方法

继续跟踪 this.refresh()的源码,该方法是在类AbstractApplicationContext中,该方法的定义在接口ConfigurableApplicationContext中。继续定位创建User对象的逻辑在哪里。方法源码如下:

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                //该方法执行完后,User对象被创建了
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var10) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                }

                this.destroyBeans();
                this.cancelRefresh(var10);
                throw var10;
            } finally {
                this.resetCommonCaches();
                contextRefresh.end();
            }
        }
    }

2.4 阅读finishBeanFactoryInitialization() 方法的源码

由执行效果可得,在执行完 finishBeanFactoryInitialization() 方法后,对象被创建了,说明创建逻辑在 finishBeanFactoryInitialization() 方法中。跟踪finishBeanFactoryInitialization()的对应源码,源码如下:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver((strVal) -> {
                return this.getEnvironment().resolvePlaceholders(strVal);
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        //执行完该方法后,对象被创建了
        beanFactory.preInstantiateSingletons();
    }

在跟踪 finishBeanFactoryInitialization()的源码可知, finishBeanFactoryInitialization()中的beanFactory.preInstantiateSingletons()执行完成后,User对象就被创建了,效果如图:

2.5 阅读preInstantiateSingletons()方法的源码

方法 preInstantiateSingletons() 是 DefaultListableBeanFactory类中的一个方法,DefaultListableBeanFactory是BeanFactory的一个实现类。preInstantiateSingletons()的源码如下:

public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Pre-instantiating singletons in " + this);
        }

        List beanNames = new ArrayList(this.beanDefinitionNames);
        Iterator var2 = beanNames.iterator();

        while(true) {
            String beanName;
            Object bean;
            do {
                while(true) {
                    RootBeanDefinition bd;
                    do {
                        do {
                            do {
                                if (!var2.hasNext()) {
                                    var2 = beanNames.iterator();

                                    while(var2.hasNext()) {
                                        beanName = (String)var2.next();
                                        Object singletonInstance = this.getSingleton(beanName);
                                        if (singletonInstance instanceof SmartInitializingSingleton) {
                                            StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);
                                            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                            if (System.getSecurityManager() != null) {
                                                AccessController.doPrivileged(() -> {
                                                    smartSingleton.afterSingletonsInstantiated();
                                                    return null;
                                                }, this.getAccessControlContext());
                                            } else {
                                                smartSingleton.afterSingletonsInstantiated();
                                            }

                                            smartInitialize.end();
                                        }
                                    }

                                    return;
                                }

                                beanName = (String)var2.next();
                                bd = this.getMergedLocalBeanDefinition(beanName);
                            } while(bd.isAbstract());
                        } while(!bd.isSingleton());
                    } while(bd.isLazyInit());

                    if (this.isFactoryBean(beanName)) {
                        bean = this.getBean("&" + beanName);
                        break;
                    }
                    //该方法执行完后,User对象被创建了
                    this.getBean(beanName);
                }
            } while(!(bean instanceof FactoryBean));

            FactoryBean factory = (FactoryBean)bean;
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                SmartFactoryBean var10000 = (SmartFactoryBean)factory;
                ((SmartFactoryBean)factory).getClass();
                isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
            } else {
                isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
            }

            if (isEagerInit) {
                this.getBean(beanName);
            }
        }
    }

 preInstantiateSingletons()中调用完this.getBean(beanName)后,对象就被创建了,说明对象的创建逻辑需要跟踪this.getBean(beanName)的方法,该方法的beanName就是配置的user。

2.6 阅读getBean()方法的源码

getBean()方法是 AbstractBeanFactory 中的getBean()方法,该getBean()方法中调用了this.doGetBean()方法,源码如下:

public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}

这里只有一行代码,所以我们还得继续跟中doGetBean()方法。

2.7 阅读doGetBean()方法的源码

doGetBean()的源码中,执行完this.getSingleton()方法后,对象创建完成,源码如下:

protected  T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
	String beanName = this.transformedBeanName(name);
	Object sharedInstance = this.getSingleton(beanName);
	Object beanInstance;
	if (sharedInstance != null && args == null) {
		if (this.logger.isTraceEnabled()) {
			if (this.isSingletonCurrentlyInCreation(beanName)) {
				this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
			} else {
				this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}

		beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
	} else {
		if (this.isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		BeanFactory parentBeanFactory = this.getParentBeanFactory();
		if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
			String nameToLookup = this.originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
			}

			if (args != null) {
				return parentBeanFactory.getBean(nameToLookup, args);
			}

			if (requiredType != null) {
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}

			return parentBeanFactory.getBean(nameToLookup);
		}

		if (!typeCheckOnly) {
			this.markBeanAsCreated(beanName);
		}

		StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);

		try {
			if (requiredType != null) {
				beanCreation.tag("beanType", requiredType::toString);
			}

			RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
			this.checkMergedBeanDefinition(mbd, beanName, args);
			String[] dependsOn = mbd.getDependsOn();
			String[] var12;
			if (dependsOn != null) {
				var12 = dependsOn;
				int var13 = dependsOn.length;

				for(int var14 = 0; var14 < var13; ++var14) {
					String dep = var12[var14];
					if (this.isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}

					this.registerDependentBean(dep, beanName);

					try {
						this.getBean(dep);
					} catch (NoSuchBeanDefinitionException var31) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var31);
					}
				}
			}

			if (mbd.isSingleton()) {
				//this.getSingleton()执行完后,User对象就被创建了
				sharedInstance = this.getSingleton(beanName, () -> {
					try {
						return this.createBean(beanName, mbd, args);
					} catch (BeansException var5) {
						this.destroySingleton(beanName);
						throw var5;
					}
				});
				beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			} else if (mbd.isPrototype()) {
				var12 = null;

				Object prototypeInstance;
				try {
					this.beforePrototypeCreation(beanName);
					prototypeInstance = this.createBean(beanName, mbd, args);
				} finally {
					this.afterPrototypeCreation(beanName);
				}

				beanInstance = this.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 = (Scope)this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}

				try {
					Object scopedInstance = scope.get(beanName, () -> {
						this.beforePrototypeCreation(beanName);

						Object var4;
						try {
							var4 = this.createBean(beanName, mbd, args);
						} finally {
							this.afterPrototypeCreation(beanName);
						}

						return var4;
					});
					beanInstance = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				} catch (IllegalStateException var30) {
					throw new ScopeNotActiveException(beanName, scopeName, var30);
				}
			}
		} catch (BeansException var32) {
			beanCreation.tag("exception", var32.getClass().toString());
			beanCreation.tag("message", String.valueOf(var32.getMessage()));
			this.cleanupAfterBeanCreationFailure(beanName);
			throw var32;
		} finally {
			beanCreation.end();
		}
	}

	return this.adaptBeanInstance(name, beanInstance, requiredType);
}

 

doGetBean()方法逻辑较多,为了不被其他代码干扰我们的思路,在debug过程中,最好不要去关注非主线思路的其他逻辑。当我们知道在doGetBean()方法中的this.getSingleton()执行完后,就创建了对象,那么就必须要继续跟踪getSingleton()的源码了。

2.8 阅读getSingleton()方法的源码

方法getSingleton()是DefaultSingletonBeanRegistry类中的一个方法,DefaultSingletonBeanRegistry是SingletonBeanRegistry接口的实现类,getSingleton方法就是在SingletonBeanRegistry接口中定义的。DefaultSingletonBeanRegistry类有个singletonObjects的Map是一个重要的集合,用来存放创建的单例bean。

getSingleton的源码如下:

public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	synchronized(this.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 (this.logger.isDebugEnabled()) {
				this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}

			this.beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = this.suppressedExceptions == null;
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet();
			}

			try {
                //getObject()方法执行完后,对象就被创建了
				singletonObject = singletonFactory.getObject();
				newSingleton = true;
			} catch (IllegalStateException var16) {
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					throw var16;
				}
			} catch (BeanCreationException var17) {
				BeanCreationException ex = var17;
				if (recordSuppressedExceptions) {
					Iterator var8 = this.suppressedExceptions.iterator();

					while(var8.hasNext()) {
						Exception suppressedException = (Exception)var8.next();
						ex.addRelatedCause(suppressedException);
					}
				}

				throw ex;
			} finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}

				this.afterSingletonCreation(beanName);
			}

			if (newSingleton) {
				this.addSingleton(beanName, singletonObject);
			}
		}

		return singletonObject;
	}
}

 getSingleton()方法最后是直接返回了,return singletonObject;说明后面就不会在有其他调用逻辑了,基本上可以得出一个小结论,这个方法执行结束后,对象肯定创建完成,而创建的过程肯定是在singletonFactory.getObject()中,我们继续跟踪singletonFactory.getObject()的源码。

2.9 阅读singletonFactory.getObject()方法的源码

singletonFactory.getObject()中是最终的创建bean对象的地方了,该方法getObject()是ObjectFactory接口的一个方法。ObjectFactory存在多个实现类,具体创建逻辑是哪个类执行,我们可以通过debug的进入执行方法的 *** 作查看。根据执行效果可以看出,逻辑执行到了this.getSingleton的参数ObjectFactory接口的匿名内部类中的this.createBean方法中。this.createBean的源码如下:

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
	if (this.logger.isTraceEnabled()) {
		this.logger.trace("Creating instance of bean '" + beanName + "'");
	}

	RootBeanDefinition mbdToUse = mbd;
	Class resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	try {
		mbdToUse.prepareMethodOverrides();
	} catch (BeanDefinitionValidationException var9) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
	}

	Object beanInstance;
	try {
		beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
		if (beanInstance != null) {
			return beanInstance;
		}
	} catch (Throwable var10) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
	}

	try {
        //执行完this.doCreateBean()方法后,对象被创建了
		beanInstance = this.doCreateBean(beanName, mbdToUse, args);
		if (this.logger.isTraceEnabled()) {
			this.logger.trace("Finished creating instance of bean '" + beanName + "'");
		}

		return beanInstance;
	} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
		throw var7;
	} catch (Throwable var8) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
	}
}

 createBean()方法是AbstractAutowireCapableBeanFactory的一个方法,该类是BeanFactory的一个实现类。跟踪createBean()时,可以看出,在执行完this.doCreateBean()后,对象被创建了,所以我们还需要继续跟进doCreateBean()的方法中继续查看Bean的创建逻辑。

2.10 阅读doCreateBean()方法的源码

doCreateBean()方法也是AbstractAutowireCapableBeanFactory类中的一个方法,该方法的源码如下:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
	}

	if (instanceWrapper == null) {
		//执行完该方法后,对象就被创建了
		instanceWrapper = this.createBeanInstance(beanName, mbd, args);
	}

	Object bean = instanceWrapper.getWrappedInstance();
	Class beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	synchronized(mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			} catch (Throwable var17) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
			}

			mbd.postProcessed = true;
		}
	}

	boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
	if (earlySingletonExposure) {
		if (this.logger.isTraceEnabled()) {
			this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
		}

		this.addSingletonFactory(beanName, () -> {
			return this.getEarlyBeanReference(beanName, mbd, bean);
		});
	}

	Object exposedObject = bean;

	try {
		this.populateBean(beanName, mbd, instanceWrapper);
		exposedObject = this.initializeBean(beanName, exposedObject, mbd);
	} catch (Throwable var18) {
		if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
			throw (BeanCreationException)var18;
		}

		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
	}

	if (earlySingletonExposure) {
		Object earlySingletonReference = this.getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
				String[] dependentBeans = this.getDependentBeans(beanName);
				Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
				String[] var12 = dependentBeans;
				int var13 = dependentBeans.length;

				for(int var14 = 0; var14 < var13; ++var14) {
					String dependentBean = var12[var14];
					if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}

				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
				}
			}
		}
	}

	try {
		this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
		return exposedObject;
	} catch (BeanDefinitionValidationException var16) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
	}
}

所以我们还得继续跟踪this.createBeanInstance()方法的逻辑。下面我们阅读createBeanInstance()的源码。

2.11 阅读createBeanInstance()方法的源码

方法createBeanInstance()是AbstractAutowireCapableBeanFactory中的方法,该方法的源码如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	Class beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
	if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
	} else {
		Supplier instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return this.obtainFromSupplier(instanceSupplier, beanName);
		} else if (mbd.getFactoryMethodName() != null) {
			return this.instantiateUsingFactoryMethod(beanName, mbd, args);
		} else {
			boolean resolved = false;
			boolean autowireNecessary = false;
			if (args == null) {
				synchronized(mbd.constructorArgumentLock) {
					if (mbd.resolvedConstructorOrFactoryMethod != null) {
						resolved = true;
						autowireNecessary = mbd.constructorArgumentsResolved;
					}
				}
			}

			if (resolved) {
				return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
			} else {
				Constructor[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
				if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
					ctors = mbd.getPreferredConstructors();
					//通过this.instantiateBean(beanName, mbd)创建了对象
					return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
				} else {
					return this.autowireConstructor(beanName, mbd, ctors, args);
				}
			}
		}
	}
}

 所以还需要this.instantiateBean(beanName, mbd)方法中继续查看源码。

2.12 阅读instantiateBean()方法的源码

方法instantiateBean()也是AbstractAutowireCapableBeanFactory类中的方法。该方法的源码如下:

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
	try {
		Object beanInstance;
		if (System.getSecurityManager() != null) {
			beanInstance = AccessController.doPrivileged(() -> {
				return this.getInstantiationStrategy().instantiate(mbd, beanName, this);
			}, this.getAccessControlContext());
		} else {
			/**
			*执行完后创建了对象
			*this.getInstantiationStrategy().instantiate(mbd, beanName, this)这行代码实际上有两步
			*1. InstantiationStrategy instantiationStrategy = this.getInstantiationStrategy();
            * InstantiationStrategy 是一个实例化策略接口
			*2. Object object = instantiationStrategy.instantiate(mbd, beanName, this)
			*/
			beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
		}

		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		this.initBeanWrapper(bw);
		return bw;
	} catch (Throwable var5) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var5);
	}
}

 2.13 阅读instantiate()方法的源码

该方法是SimpleInstantiationStrategy类中,该类实现了InstantiationStrategy接口,InstantiationStrategy用于对象实例化,源码如下:

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
	if (!bd.hasMethodOverrides()) {
		Constructor constructorToUse;
		synchronized(bd.constructorArgumentLock) {
			constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod;
			if (constructorToUse == null) {
				Class clazz = bd.getBeanClass();
				if (clazz.isInterface()) {
					throw new BeanInstantiationException(clazz, "Specified class is an interface");
				}

				try {
					if (System.getSecurityManager() != null) {
						clazz.getClass();
						constructorToUse = (Constructor)AccessController.doPrivileged(() -> {
							return clazz.getDeclaredConstructor();
						});
					} else {
						constructorToUse = clazz.getDeclaredConstructor();
					}

					bd.resolvedConstructorOrFactoryMethod = constructorToUse;
				} catch (Throwable var9) {
					throw new BeanInstantiationException(clazz, "No default constructor found", var9);
				}
			}
		}
		//执行完该方法后,对象就被创建了
		return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
	} else {
		return this.instantiateWithMethodInjection(bd, beanName, owner);
	}
}

从源码中可得,BeanUtils就是创建Bean的一个工具类,调用instantiateClass()方法进行创建,instantiateClass()方法的参数是构造器对象和参数。我们继续阅读instantiateClass的源码

2.14 阅读instantiateClass()方法的源码

该方法是BeanUtils的一个方法,用于创建Bean对象,从源码中可知,spring创建Bean的实例对象是通过反射的方式来创建的。其源码如下:

public static  T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {
	Assert.notNull(ctor, "Constructor must not be null");

	try {
		ReflectionUtils.makeAccessible(ctor);
		if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
			return BeanUtils.KotlinDelegate.instantiateClass(ctor, args);
		} else {
			Class[] parameterTypes = ctor.getParameterTypes();
			Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
			Object[] argsWithDefaultValues = new Object[args.length];

			for(int i = 0; i < args.length; ++i) {
				if (args[i] == null) {
					Class parameterType = parameterTypes[i];
					argsWithDefaultValues[i] = parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null;
				} else {
					argsWithDefaultValues[i] = args[i];
				}
			}
			//使用反射的方式创建对象
			return ctor.newInstance(argsWithDefaultValues);
		}
	} catch (InstantiationException var6) {
		throw new BeanInstantiationException(ctor, "Is it an abstract class?", var6);
	} catch (IllegalAccessException var7) {
		throw new BeanInstantiationException(ctor, "Is the constructor accessible?", var7);
	} catch (IllegalArgumentException var8) {
		throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", var8);
	} catch (InvocationTargetException var9) {
		throw new BeanInstantiationException(ctor, "Constructor threw exception", var9.getTargetException());
	}
}

 到此,spring创建一个Bean的所有流程就全部结束了,我们可以对这个流程做一个简单的总结,spring创建非懒加载的Bean的过程是发成在容器ApplicationContext实例化的过程中完成,在容器的内部会创建一个BeanFactory,再使用beanFactory的getBean()方法,getBean方式中会调用doGetBean方法进行创建Bean。并且常见后,会将Bean存放在一个Map集合(singletonObjects)中,Map中的key就是我们配置文件中定义的bean标签的id值。以上就是我在跟踪spring创建Bean过程中的一些分享。如有疑问,欢迎讨论!!!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/798103.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存