相关文章
Spring IOC系列学习笔记一:前置刷新
Spring IOC系列学习笔记二:obtainFreshBeanFactory方法
Spring IOC系列学习笔记三:parseDefaultElement详解
Spring IOC系列学习笔记四:parseCustomElement解析
Spring IOC系列学习笔记五:context:component-scan 节点解析
Spring IOC系列学习笔记六:invokeBeanFactoryPostProcessors解析
Spring IOC系列学习笔记七:registerBeanPostProcessors
Spring IOC系列学习笔记八:finishBeanFactoryInitialization
Spring IOC系列学习笔记九:getBean方法
Spring IOC系列学习笔记十:createBean方法(上)
Spring IOC系列学习笔记十一:createBean方法(下)
Spring IOC系列学习笔记十二:@Autowire注解
文章目录
- 相关文章
- 前言
- 代码块一:createBean
- 代码块二:resolveBeforeInstantiation
- 代码块三:doCreateBean
- 代码块四:createBeanInstance
- 代码块五:determineConstructorsFromBeanPostProcessors
- 代码块六:autowireConstructor
- 代码块七:resolveConstructorArguments
- 代码块八:createArgumentArray
- 代码块九:resolveAutowiredArgument
- 代码块十:resolveDependency
- 代码块十一:doResolveDependency
- 代码块 十二:findAutowireCandidates
- 代码块十三:addCandidateEntry
- 代码块十四:determineAutowireCandidate
- 代码块十五:storeCache
- 总结
前言
继续前面getBean的讲解进入createBean方法。
代码块一:createBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
1、解析beanName对应的bean类型,例如com.zgf.service.impl.AccountServiceImpl
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
2、resolvedClass不为空&&mbd的beanClass不是Class类型&&mbd的beanClassName不为空,则mbd的beanClass保存的是class的Name
复制一份取代mbd后续的操作
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
3、用InstantiationAwareBeanPostProcessor创建一个代理的bean进行拦截并返回,达到'短路'效果。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
4、真正创建bean的方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
5、返回bean实例
return beanInstance;
}
catch (BeanCreationException ex) {
// A previously detected exception with proper bean creation context already...
throw ex;
}
catch (ImplicitlyAppearedSingletonException ex) {
// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
3、用InstantiationAwareBeanPostProcessor创建一个代理的bean进行拦截并返回,达到’短路’效果。见代码块二
4、真正创建bean的方法见代码块三
代码块二:resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
1、mbd不是合成的&&BeanFactory中存在InstantiationAwareBeanPostProcessors接口
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
2、前置处理
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
3、后置处理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
4、如果bean不为空,则将beforeInstantiationResolved赋值为true,代表在实例化之前已经解析
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
在实例化之前执行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。
代码块三:doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
1、bean的包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
1.1、判断beanName是否是factoryBean,如果是则移除未完成bean的缓存
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
2、如果不是factoryBean则创建beanName的包装类
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
3.1、获取bean实例
final Object bean = instanceWrapper.getWrappedInstance();
3.2、获取bean的实例类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
3.3、如果bean实例的类型不是空则设置实例类型到mbd
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
4.1、MergedBeanDefinitionPostProcessor的后置处理,允许修改bean
4.2、@Autowired正式通过这儿预解析的
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
5.1、判断bean是否提前早期循环引用,提前曝光。
5.2、mbd是单例的&&允许循环依赖&&当前bean正在被创建
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
6.1、getEarlyBeanReference:利用SmartInstantiationAwareBeanPostProcessor的后置处理返回bean的早期引用,如果没有则返回bean本身
6.2、提前曝光bean,添加到单例工厂解决循环引用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
7、属性填充
populateBean(beanName, mbd, instanceWrapper);
8、初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
9.1、如果允许早期曝光,进行循环依赖检查
if (earlySingletonExposure) {
9.2、earlySingletonReference在存在循环依赖的情况下不为null
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
9.3、如果在初始化bean的时候没有改变bean对象,则不影响之前的循环引用
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
9.4、如果bean在初始化的时候被改变了,则原先的循环引用受影响,因为引用的是旧数据需要剔除掉,引用最新的bean对象
9.5、获取依赖于当前beanName的所有的bean的Name数组
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
9.6、尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
9.7、移除失败的添加到actualDependentBeans中
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
9.8、如果存在移除失败的,则抛出异常,因为存在bean依赖了“脏数据”
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
10、注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
11、返回创建的bean
return exposedObject;
}
真正创建bean的方法,是该系列的核心方法,相对来说较为复杂,需要反复阅读。
2、如果不是factoryBean则创建beanName的包装类见代码块四。
代码块四:createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
1、解析bean的类型信息
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
2、如果bean类型为空&&beanClass不是公开类&&不允许被非公共类访问
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
3、 是否有bean的 Supplier 接口,如果有,通过回调来创建bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
4、如果工厂方法不为空,则使用工厂方法创建实例
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
5.1、resolved构造函数是否已经解析过标志;autowireNecessary是否需要自动装配
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
5.2、构造函数或工厂方法已经解析
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
6.1、该bean构造函数已经解析,并且需要自动装配,使用构造函数自动注入进行实例化
return autowireConstructor(beanName, mbd, null, null);
}
else {
6.2、该bean构造函数已经解析,不需要自动装配,使用默认的构造函数进行实例化
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
7.1、拿到bean的候选的构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
7.2、ctors不为空||mbd的注入方式为AUTOWIRE_CONSTRUCTOR||mbd定义了构造函数参数||显性构造参数args不为空
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
8.都不满足则使用默认的构造函数进行初始化
return instantiateBean(beanName, mbd);
}
- 继承了Supplier接口,则通过Supplier 创建bean实例。
- 如果RootBeanDefinition 中存在 factoryMethodName
属性,或者在配置文件中配置了factory-method,Spring会尝试使用 instantiateUsingFactoryMethod 方法,根据RootBeanDefinition 中的配置生成bean实例。需要注意的是,如果一个类中中的方法被 @Bean注解修饰,那么Spring则会将其封装成一个 ConfigurationClassBeanDefinition。此时 factoryMethodName 也被赋值。所以也会调用instantiateUsingFactoryMethod 方法通过反射完成方法的调用,并将结果注入Spring容器中。 - 不是如上两种方法,则尝试使用构造函数来进行实例化。首先检查bean是否已经有了构造函数缓存,这儿用的是resolvedConstructorOrFactoryMethod缓存。
- 如果缓存存在,如果需要自动装配则通过autowireConstructor方法来进行实例,反之使用默认的instantiateBean 方法。(有参数用autowireConstructor,无参数用instantiateBean )
- 缓存不存在首先通过determineConstructorsFromBeanPostProcessors方法获取候选构造函数,进行最终的选择,通过autowireConstructor或者instantiateBean。在 autowireConstructor中进行了候选构造函数的选举,选择最合适的构造函数来构建bean,如果缓存已解析的构造函数,则不用选举,直接使用解析好的构造来进行bean的创建。
6.1、构造函数自动注入见代码块六
7.1、获取候选的构造函数见代码块五
代码块五:determineConstructorsFromBeanPostProcessors
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
1、遍历所有的BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
2.调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法,
该方法可以返回要用于beanClass的候选构造函数
例如:使用@Autowire注解修饰构造函数,则该构造函数在这边会被AutowiredAnnotationBeanPostProcessor找到
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
3.如果ctors不为空,则不再继续执行其他的SmartInstantiationAwareBeanPostProcessor
return ctors;
}
}
}
}
return null;
}
2.调用 SmartInstantiationAwareBeanPostProcessor 的 determineCandidateConstructors 方法,该方法可以返回要用于 beanClass 的候选构造函数。使用 @Autowire 注解修饰构造函数,则该构造函数在这边会被 AutowiredAnnotationBeanPostProcessor 找到,该内容会在之后介绍 @Autowire 的文章中单独介绍。
代码块六:autowireConstructor
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {
1、创建bean的包装类
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
2.1、最终实例化的构造函数
Constructor<?> constructorToUse = null;
2.2、最终实例化的参数持有者
ArgumentsHolder argsHolderToUse = null;
2.4、最终实例化的构造函数参数数组
Object[] argsToUse = null;
3、显式指定了构造函数的参数,则使用该参数
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
4.1、尝试从缓存中获取构造函数参数
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
4.2、从缓存中获取已经解析的构造函数或工厂方法
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
4.3、如果constructorToUse不为空&&构造函数参数已经解析
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
4.4、获取已经解析过的构造函数参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
4.5、如果argsToUse为空,则获取已经准备好解析的构造函数参数
这儿如果mbd.constructorArgumentsResolved为true时,构造函数参数一定是已经解析或者准备解析肯定有一个已经缓存了参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
4.6、解析准备好的构造函数参数
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
5.1、如果缓存中没有构造函数
if (constructorToUse == null) {
// Need to resolve the constructor.
5.2、如果chosenCtors不为空||autowireMode是AUTOWIRE_CONSTRUCTOR,则需要自动注入
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
5.3、构造函数参数个数
int minNrOfArgs;
if (explicitArgs != null) {
5.4、如果显性指定了构造参数,则获取长度
minNrOfArgs = explicitArgs.length;
}
else {
5.5、mbd的构造参数值indexedArgumentValues缓存的是带index的值 genericArgumentValues缓存的是通用的值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
5.6、承载解析后的构造参数的值
resolvedValues = new ConstructorArgumentValues();
5.7、解析mbd的构造函数的参数,并返回参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
// 注:这边解析mbd中的构造函数参数值,主要是处理我们通过xml方式定义的构造函数注入的参数,
// 但是如果我们是通过@Autowire注解直接修饰构造函数,则mbd是没有这些参数值的
}
// Take specified constructors, if any.
6.1、获取所有候选的构造函数,如果chosenCtors不为空就是候选的
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
6.2、如果构造函数可以被非公有的访问,则获取所有的,反之只获取共有的构造函数
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
7、对候选构造函数进行排序,public构造函数参数由多到少,非public参数由多到少
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
8.摸棱两可的构造函数,差矣权值相等切最小的两个构造函数
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
9.1、遍历所有的候选构造函数
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
9.2、已经找到了合适的构造函数&&构造函数参数个数大于当前构造函数参数个数,跳出循环
因为已经找到了合适的构造函数,且参数个数降序,不需要比较
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
9.3、当前候选构造参数个数小于需要的构造参数,直接跳过,肯定不合适
if (paramTypes.length < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
10.1、 resolvedValues不为空
try {
10.2、解析使用ConstructorProperties注解的构造函数参数
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
10.3、获取参数名称解析器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
10.4、使用参数名称解析器获取当前遍历的构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
10.5、主要是通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean)
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch (UnsatisfiedDependencyException ex) {
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
11.1、如果resolvedValues为空,当前函数参数不等于显性指定的参数,跳过继续寻找
if (paramTypes.length != explicitArgs.length) {
continue;
}
11.2、使用显性参数构造ArgumentsHolder
argsHolder = new ArgumentsHolder(explicitArgs);
}
12.1、将argsHolder的参数和paramTypes进行比较,计算paramTypes的类型差异权重值
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
12.2、类型差异权重值越小,则说明构造函数越匹配,则选择此构造函数
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
12.3、如果出现权重值更小的候选者,则将ambiguousConstructors清空,允许之前存在权重值相同的候选者
ambiguousConstructors = null;
}
12.4、如果存在两个候选者的权重值相同,并且是当前遍历过权重值最小的
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
12.5、添加到ambiguousConstructors
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
if (causes != null) {
如果最终没有找到匹配的构造函数,则进行异常处理
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
如果找到了匹配的构造函数,但是存在多个(ambiguousConstructors不为空) && 解析构造函数的模式为严格模式,则抛出异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null) {
13、将解析的构造函数和参数放到缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
14、根据实例化策略以及得到的构造函数及构造函数参数实例化bean。
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
15、设置实例到包装类返回
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
大体流程:
- 是否显性指定了构造参数,如果显性指定了就是用explicitArgs作为构造参数。
- 如果没有指定构造参数,则从缓存中获取,就是从resolvedConstructorArguments已经解析好的,preparedConstructorArguments中准备解析的。
- 没有从缓存中获取到构造函数,则通过入参的chosenCtors作为候选构造函数,如果chosenCtors为null,则通过反射获取候选构造函数。
- 对 candidates 按照 public 构造函数优先参数数量降序,非public构造函数参数数量降序
规则排序,目的是为了后面检索的时候可以更快速判断是否有合适的构造函数。 - 遍历构造函数,选择匹配差异最小的构造函数来创建bean实例。
5.7、析mbd的构造函数的参数,并返回参数个数见代码块七
10.5、主要是通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean)见代码块八
13、将解析的构造函数和参数放到缓存见代码块
代码块七:resolveConstructorArguments
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
// 1.构建bean定义值解析器
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
// 2.minNrOfArgs初始化为indexedArgumentValues和genericArgumentValues的的参数个数总和
int minNrOfArgs = cargs.getArgumentCount();
// 3.遍历解析带index的参数值
for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
int index = entry.getKey();
if (index < 0) {
// index从0开始,不允许小于0
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid constructor argument index: " + index);
}
// 3.1 如果index大于minNrOfArgs,则修改minNrOfArgs
if (index > minNrOfArgs) {
// index是从0开始,并且是有序递增的,所以当有参数的index=5时,代表该方法至少有6个参数
minNrOfArgs = index + 1;
}
ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
// 3.2 解析参数值
if (valueHolder.isConverted()) {
// 3.2.1 如果参数值已经转换过,则直接将index和valueHolder添加到resolvedValues的indexedArgumentValues属性
resolvedValues.addIndexedArgumentValue(index, valueHolder);
} else {
// 3.2.2 如果值还未转换过,则先进行转换
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 3.2.3 使用转换后的resolvedValue构建新的ValueHolder
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
// 3.2.4 将转换前的valueHolder保存到新的ValueHolder的source属性
resolvedValueHolder.setSource(valueHolder);
// 3.2.5 将index和新的ValueHolder添加到resolvedValues的indexedArgumentValues属性
resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
}
}
// 4.遍历解析通用参数值(不带index)
for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
if (valueHolder.isConverted()) {
// 4.1 如果参数值已经转换过,则直接将valueHolder添加到resolvedValues的genericArgumentValues属性
resolvedValues.addGenericArgumentValue(valueHolder);
} else {
// 4.2 如果值还未转换过,则先进行转换
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 4.3 使用转换后的resolvedValue构建新的ValueHolder
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
// 4.4 将转换前的valueHolder保存到新的ValueHolder的source属性
resolvedValueHolder.setSource(valueHolder);
// 4.5 将新的ValueHolder添加到resolvedValues的genericArgumentValues属性
resolvedValues.addGenericArgumentValue(resolvedValueHolder);
}
}
// 5.返回构造函数参数的个数
return minNrOfArgs;
}
代码块八:createArgumentArray
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
boolean autowiring) throws UnsatisfiedDependencyException {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
1、用于存放匹配的参数
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
2.1、遍历类构造参数数组
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
2.2、拿到当前的参数类型
Class<?> paramType = paramTypes[paramIndex];
2.3、拿到当前的参数名
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// Try to find matching constructor argument value, either indexed or generic.
ConstructorArgumentValues.ValueHolder valueHolder = null;
if (resolvedValues != null) {
2.4、验证当前遍历的参数名,参数类型,index,与配置是否匹配(就是对比xml的构造参数配置和类中的构造方法)
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// If we couldn't find a direct match and are not supposed to autowire,
// let's try the next generic, untyped argument value as fallback:
// it could match after type conversion (for example, String -> int).
2.5、如果找不到匹配的&&不是自动装配的,尝试一下降级,比如String匹配int类型
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
usedValueHolders.add(valueHolder);
3.1、获取原始的值
Object originalValue = valueHolder.getValue();
3.2、用来存放转换后的值
Object convertedValue;
if (valueHolder.isConverted()) {
3.3、如果已经转换了,获取转换后得值
convertedValue = valueHolder.getConvertedValue();
3.4、存放在args对应的位置作为预备参数
args.preparedArguments[paramIndex] = convertedValue;
}
else {
3.5、没有转换,将方法(此处为构造函数)和参数索引封装成MethodParameter(MethodParameter是封装方法和参数索引的工具类)
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
3.5、进行转换
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
}
catch (TypeMismatchException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Could not convert argument value of type [" +
ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
Object sourceHolder = valueHolder.getSource();
if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
3.5、如果sourceHolder是ConstructorArgumentValues.ValueHolder类型的代表还未解析
Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
3.6、标志为需要解析
args.resolveNecessary = true;
3.7、保存到预备参数中
args.preparedArguments[paramIndex] = sourceValue;
}
}
3.8、将convertedValue作为args在paramIndex位置的参数
args.arguments[paramIndex] = convertedValue;
3.9、将originalValue作为args在paramIndex位置的原始参数
args.rawArguments[paramIndex] = originalValue;
}
else {
4.1、不存在匹配的参数,valueHolder为null
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
4.2、如果不是自动注入则直接抛出异常,因为有两种方式配置构造参数,自动注入和xml非自动注入配置,前面已经解析了xml配置现在要解析自动注入
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
try {
4.3、如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象
例如:@Autowire修饰构造函数,自动注入构造函数中的参数bean就是在这边处理
Object autowiredArgument =
resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter);
4.4、将通过自动装配解析出来的参数赋值给args
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
args.resolveNecessary = true;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
5.1、有依赖的bean的话注册依赖关系
for (String autowiredBeanName : autowiredBeanNames) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (this.beanFactory.logger.isDebugEnabled()) {
this.beanFactory.logger.debug("Autowiring by type from bean name '" + beanName +
"' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
" to bean named '" + autowiredBeanName + "'");
}
}
return args;
}
4.3、如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象见代码块九
代码块九:resolveAutowiredArgument
protected Object resolveAutowiredArgument(
MethodParameter param, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) {
1、如果参数类型为InjectionPoint
if (InjectionPoint.class.isAssignableFrom(param.getParameterType())) {
1、1 拿到当前的InjectionPoint(存储了当前正在解析依赖的方法参数信息,DependencyDescriptor)
InjectionPoint injectionPoint = currentInjectionPoint.get();
if (injectionPoint == null) {
1、2 当前injectionPoint为空,则抛出异常:目前没有可用的InjectionPoint
throw new IllegalStateException("No current InjectionPoint available for " + param);
}
1、3 返回当前的InjectionPoint
return injectionPoint;
}
2、解析指定依赖,DependencyDescriptor:将MethodParameter的方法参数索引信息封装成DependencyDescriptor
return this.beanFactory.resolveDependency(
new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
}
2、解析指定的依赖见代码块十
代码块十:resolveDependency
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
1、Optional类注入的特殊处理
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
2、ObjectFactory或者ObjectProvider的处理
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
3、Jsr330ProviderFactory类的处理
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
4、通用类的处理,上述三个处理方式其实最后都会走通用的处理方式
4.1、延迟加载
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
4.2、不是延迟加载,解析返回bean实例
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
大致流程:
- Optional:JDK8 提供了 API。主要是将依赖设置非强制依赖,即 descriptor.required=false。
- 延迟依赖注入支持:ObjectFactory、ObjectProvider、javax.inject.Provider 没有本质的区别。
- 另一种延迟注入的支持 - @Lazy 属性。
- 根据类型查找依赖 - doResolveDependency。
4.2、不是延迟加载,解析返回bean实例见代码块十一
代码块十一:doResolveDependency
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
1、直接通过getBean的方式获取
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
2、拿到当前字段参数的类型
Class<?> type = descriptor.getDependencyType();
2.1、获取@Value注解的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
2.2、解析String的值,比如解析占位符等
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
2.3、转换成所需的类型并返回比如 @Value("郑国锋") 则返回的就是"郑国锋"
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
3、解析复杂的类型比如:Array,List,Map,Collection等
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
4、不是上述的类型,则查找所需要类型的bean实例,map(key:bean的名字;value:bean的实例或者bean的实例类型)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
4.1、如果require属性为true,而找到的匹配Bean却为空则抛出异常
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
4.2、如果require属性为false,而找到的匹配Bean却为空,则返回null
return null;
}
5.1、最终实例名字
String autowiredBeanName;
5.2、最终实例或者实例类型
Object instanceCandidate;
if (matchingBeans.size() > 1) {
5.3、如果候选实例不唯一,需要选取最优的,返回name
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
5.4、拿到autowiredBeanName的bean实例或者bean实例类型
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
5.5、如果唯一则直接用这个
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
6.1、将依赖的beanName加到autowiredBeanNames中
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
7、如果instanceCandidate实例类型,则解析成bean实例
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
流程:
- 直接通过getBean的方式获取
- @Value 注解处理场景
- 集合依赖查询
- 单个依赖查询
4、查找bena候选的bena实例见代码块十二
5.3、如果候选实例不唯一,需要选取最优的见代码块十四
代码块 十二:findAutowireCandidates
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
1、获取当前参数类型的所有的beanNname
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
2、从spring内部缓存resolvableDependencies获取
for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
if (autowiringType.isAssignableFrom(requiredType)) {
2.1、判断autowiringType和requiredType类型是否匹配
2.2、获取bean实例
Object autowiringValue = this.resolvableDependencies.get(autowiringType);
2.3、根据给定的所需类型解析给定的自动装配值
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
2.4、如果autowiringValue是requiredType类型的则直接放到result,此时value为bena实例
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
3.1、遍历从容器中的beanName
for (String candidate : candidateNames) {
3.2、不是自身引用&&有资格作为候选者
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
3.3、把候选者添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
4、以上没有获取到实例放入到result中&&不是复杂的类型则使用降级匹配
if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
5、如果使用降级匹配结果还是空,则考虑自引用
if (result.isEmpty()) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
isAutowireCandidate 方法过滤候选对象有三重规则:①bd.autowireCandidate=true -> ②泛型匹配 -> ③@Qualifier。
3.3、把候选者添加到result中见代码块十三
代码块十三:addCandidateEntry
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
// 1.如果descriptor为MultiElementDescriptor类型 || candidateName已经在singletonObjects缓存中存在
if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) {
// 2.1 resolveCandidate: 通过candidateName获取对应的bean实例
// 2.2 将beanName -> bean实例 的映射添加到candidates(此时的value为bean实例)
candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this));
} else {
// 3.将beanName -> bean实例的类型 的映射添加到candidates(此时的value为bean实例的类型)
candidates.put(candidateName, getType(candidateName));
}
}
回到代码块十一5.3,进入代码块十四选取最优的候选者。
代码块十四:determineAutowireCandidate
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
1、根据@Primary注解来选择最优解
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
2、根据@Priority选取最优解
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
3、如果通过以上两步都不能选择出最优解,则使用最基本的策略
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
3.1、containsValue:首先如果这个beanInstance已经由Spring注册过依赖关系,则直接使用该beanInstance作为最优解
3.2、atchesBeanName:如果没有注册过此beanInstance的依赖关系,则根据参数名称来匹配
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
protected boolean matchesBeanName(String beanName, String candidateName) {
// candidateName与beanName相等 || beanName有别名与candidateName相等,则返回true
return (candidateName != null &&
(candidateName.equals(beanName) || ObjectUtils.containsElement(getAliases(beanName), candidateName)));
}
回到代码块六13进入代码块十五将解析的构造函数和参数放到缓存
代码块十五:storeCache
public void storeCache(RootBeanDefinition mbd, Object constructorOrFactoryMethod) {
synchronized (mbd.constructorArgumentLock) {
// 将构造函数或工厂方法放到resolvedConstructorOrFactoryMethod缓存
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
// constructorArgumentsResolved标记为已解析
mbd.constructorArgumentsResolved = true;
if (this.resolveNecessary) {
// 如果参数需要解析,则将preparedArguments放到preparedConstructorArguments缓存
mbd.preparedConstructorArguments = this.preparedArguments;
} else {
// 如果参数不需要解析,则将arguments放到resolvedConstructorArguments缓存
mbd.resolvedConstructorArguments = this.arguments;
}
}
}
将解析出来的构造函数和参数放到缓存,在开头的代码块六,就检查过这些缓存。
总结
本文介绍了创建 bean 实例中的一个重要内容:创建一个新的 bean 实例。创建 bean 实例中剩下的:填充属性、bean 实例初始化等内容,将在下篇文章介绍。