Spring IoC源码:createBean
创始人
2024-02-29 06:05:57
0

前言

前面讲解了getBean方法如何获取创建一个Bean,根据传入的beanName从缓存中进行查找,查询不到则调用createBean方法进行创建,本篇文章深入讲解createBean的创建过程。

正文

回到getSingleton方法中,我们知道参数是ObjectFactory对象,通过调用其getObject方法进行对象的创建过程。

	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 (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}//添加到singletonsCurrentlyInCreation缓存中beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {//调用ObjectFactory对象的getObject方法返回实例,getObject方法的实现就是传参时的匿名内部类singletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {// Has the singleton object implicitly appeared in the meantime ->// if yes, proceed with it since the exception indicates that state.singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throw ex;}}catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throw ex;}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}//从singletonsCurrentlyInCreation缓存中移除afterSingletonCreation(beanName);}//添加到一级缓存中,移除二级缓存、三级缓存if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}}

singletonFactory方法参数值为一个类型为ObjectFactory的匿名内部类,所以调用getObject方法,其实就是调用createBean(beanName, mbd, args),这个方法。

					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;}});

createBean(beanName, mbd, args),见方法1详解

方法1:createBean

	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("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.//获取bean对应的class对象,并设置到RootBeanDefinition 定义信息中Class resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.//解析overrides属性,如xml配置中的lookup-method和replace-methodtry {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.//实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果//看BeanPostProcessors集合中是否有InstantiationAwareBeanPostProcessor类型的对象,有则尝试进行代理。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 {//普通Bean的创建过程Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}

mbdToUse.prepareMethodOverrides(),见方法2详解
resolveBeforeInstantiation(beanName, mbdToUse),见方法3详解
doCreateBean(beanName, mbdToUse, args),见方法5详解

方法2:prepareMethodOverrides

	public void prepareMethodOverrides() throws BeanDefinitionValidationException {// Check that lookup methods exist and determine their overloaded status.//判断当前Bean定义信息中是否有methodOverrides标识if (hasMethodOverrides()) {//遍历校验当前bean中是否存在该方法getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);}}/*** Validate and prepare the given method override.* Checks for existence of a method with the specified name,* marking it as not overloaded if none found.* @param mo the MethodOverride object to validate* @throws BeanDefinitionValidationException in case of validation failure*/protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {//查询校验是否存在override属性值对应的方法int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());if (count == 0) {throw new BeanDefinitionValidationException("Invalid method override: no method with name '" + mo.getMethodName() +"' on class [" + getBeanClassName() + "]");}else if (count == 1) {// Mark override as not overloaded, to avoid the overhead of arg type checking.mo.setOverloaded(false);}}

当前bean定义信息中如果有overrides属性,则校验所配置的方法名称在该bean中是否存在。

方法3:resolveBeforeInstantiation

	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;//默认该属性为falseif (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.//不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessorif (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {//获取beanName对应的class对象Class targetType = determineTargetType(beanName, mbd);if (targetType != null) {//执行InstantiationAwareBeanPostProcessor类型的postProcessBeforeInstantiation方法,并返回实例bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {//执行所有BeanPostProcessor后置处理器的postProcessAfterInitializationbean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}

isSynthetic一般用来跳过beanPostProcessor执行。
applyBeanPostProcessorsBeforeInstantiation(targetType, beanName),见方法4详解

方法4:applyBeanPostProcessorsBeforeInstantiation

protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) {//遍历执行InstantiationAwareBeanPostProcessor类型对象的postProcessBeforeInstantiation方法for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}}return null;}

这个有点类似拦截器,通过自定义一个InstantiationAwareBeanPostProcessor类型的后置处理器,并bean进行处理,返回最终的实例对象

方法5:doCreateBean

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {//如果是单例并且是FactoryBean则尝试移除instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {//创建Bean实例,通过策略进行创建,如果选择有参构造或无参构造instanceWrapper = createBeanInstance(beanName, mbd, args);}//获取当前实例对象final Object bean = instanceWrapper.getWrappedInstance();//当前实例的Calss对象Class beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {//设置当前bean定义信息的目标类型mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {//执行MergedBeanDefinitionPostProcessor类型后置处理器的postProcessMergedBeanDefinition方法,//如@Autowire注解,就是通过该后置处理器进行解析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.//如果是单例,允许循环依赖,并且beanName正在创建中boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}//包装成FactoryObject对象,并添加到三级缓存中addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {//初始化过程,进行属性注入。该过程递归创建其依赖的属性。如果A中有B,B中有C,则创建B跟C。populateBean(beanName, mbd, instanceWrapper);//该过程执行后置处理器的before方法,bean的init方法,后置处理器的after方法,可能会生成新的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);}}if (earlySingletonExposure) {//从缓存中获取,因为上面我们将其添加到三级缓存中,从三级缓存中获取会调用FactoryObject对象的getObject方法,可能会触发AOP代理。返回代理对象Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {//如果bean对象还是原来的,则将三级缓存中获取的对象赋值过去if (exposedObject == bean) {exposedObject = earlySingletonReference;}//如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {//	获取依赖当前beanName的所有bean名称String[] dependentBeans = getDependentBeans(beanName);Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);//尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据for (String dependentBean : dependentBeans) {if (!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 " +"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {//注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessorregisterDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}

createBeanInstance(beanName, mbd, args),见方法6详解

方法6:createBeanInstance

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.//解析class信息Class beanClass = resolveBeanClass(mbd, beanName);//判断 beanClass不为空 && beanClass不是public修饰 && 该bean不允许访问非公共构造函数和方法,则抛异常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());}//使用Supplier的方式直接创建beanSupplier instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}//使用工厂方法实例化bean对象if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...//标识是否解析boolean resolved = false;boolean autowireNecessary = false;if (args == null) {synchronized (mbd.constructorArgumentLock) {//判断构造函数或者工厂方法缓存中是否有值if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;//构造函数解析标识autowireNecessary = mbd.constructorArgumentsResolved;}}}if (resolved) {if (autowireNecessary) {//使用有参构造函数创建实例return autowireConstructor(beanName, mbd, null, null);}else {//使用无参构造函数创建实例return instantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?//调用SmartInstantiationAwareBeanPostProcessor类型的determineCandidateConstructors方法,返回构造函数Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);//解析的构造器不为空 || 注入类型为构造函数自动注入 || bean定义中有构造器参数 || 传入参数不为空if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?//获取默认构造器ctors = mbd.getPreferredConstructors();if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);}// No special handling: simply use no-arg constructor.//使用无参构造方法return instantiateBean(beanName, mbd);}

obtainFromSupplier(instanceSupplier, beanName),见方法7详解

determineConstructorsFromBeanPostProcessors(beanClass, beanName),见方法8详解

autowireConstructor(beanName, mbd, null, null);,见方法9详解

instantiateBean(beanName, mbd),见方法12详解

方法7:obtainFromSupplier

	protected BeanWrapper obtainFromSupplier(Supplier instanceSupplier, String beanName) {Object instance;//获取当前正在创建的BeanNameString outerBean = this.currentlyCreatedBean.get();//设置当前beanName到当前线程中this.currentlyCreatedBean.set(beanName);try {//调用Supplier的get自定义方法,创建实例对象instance = instanceSupplier.get();}finally {if (outerBean != null) {this.currentlyCreatedBean.set(outerBean);}else {this.currentlyCreatedBean.remove();}}if (instance == null) {instance = new NullBean();}//封装成BeanWrapper 包装类BeanWrapper bw = new BeanWrapperImpl(instance);initBeanWrapper(bw);return bw;}

方法8: determineConstructorsFromBeanPostProcessors

	protected Constructor[] determineConstructorsFromBeanPostProcessors(@Nullable Class beanClass, String beanName)throws BeansException {if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;//调用determineCandidateConstructors方法,按照策略查询构造函数//如果bean的构造函数带有@Autowire注解或有且仅有一个有参构造函数则会被解析到Constructor[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);if (ctors != null) {return ctors;}}}}return null;}

加果有多个@Autowired,required为true,不管有没有默认构造方法,会报异常
如果只有一个@Autowired,required,为false,但有默认构造方,会报警告
其他情况都可以,但是以有@Autowired的构造方法优先,然后才是默认构造方法

方法9:autowireConstructor

	protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor[] ctors, @Nullable Object[] explicitArgs) {return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);}
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,@Nullable Constructor[] chosenCtors, @Nullable Object[] explicitArgs) {BeanWrapperImpl bw = new BeanWrapperImpl();//初始化设置this.beanFactory.initBeanWrapper(bw);//最终使用的构造器Constructor constructorToUse = null;//最终用于实例化的参数HolderArgumentsHolder argsHolderToUse = null;//最终使用的参数值Object[] argsToUse = null;//如果有带参数,则进行赋值给argsToUse if (explicitArgs != null) {argsToUse = explicitArgs;}else {Object[] argsToResolve = null;synchronized (mbd.constructorArgumentLock) {//尝试获取缓存中的构造方法或工厂方法constructorToUse = (Constructor) mbd.resolvedConstructorOrFactoryMethod;if (constructorToUse != null && mbd.constructorArgumentsResolved) {// Found a cached constructor...//获取已经解析的构造函数参数值argsToUse = mbd.resolvedConstructorArguments;if (argsToUse == null) {//解析生成构造函数参数值argsToResolve = mbd.preparedConstructorArguments;}}}if (argsToResolve != null) {argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);}}if (constructorToUse == null || argsToUse == null) {// Take specified constructors, if any.//将传递进来的构造器赋值给最终使用的构造器Constructor[] candidates = chosenCtors;if (candidates == null) {//获取当前bean的class对象Class beanClass = mbd.getBeanClass();try {//如果允许访问非公共的构造方法,则获取全部构造方法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);}}//如果只有一个构造函数,并且没有传递参数值if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {//获取构造函数,判断参数值是否为0Constructor uniqueCandidate = candidates[0];if (uniqueCandidate.getParameterCount() == 0) {synchronized (mbd.constructorArgumentLock) {//设置当前构造函数mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;//设置确定当前构造函数标识mbd.constructorArgumentsResolved = true;//设置构造函数参数值标识mbd.resolvedConstructorArguments = EMPTY_ARGS;}//实例化bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));return bw;}}// Need to resolve the constructor.//判断是否有传递进来的构造函数,如果@Autowire修饰的构造函数,则会有值boolean autowiring = (chosenCtors != null ||mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);ConstructorArgumentValues resolvedValues = null;//最少参数个数int minNrOfArgs;//如果有传递进来的参数,则取传递的个数if (explicitArgs != null) {minNrOfArgs = explicitArgs.length;}else {//获得mbd的构造函数的参数值(indexedArgumentValues:带index的参数值;genericArgumentValues:通用的参数值)ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();resolvedValues = new ConstructorArgumentValues();//将参数值分类封装成ConstructorArgumentValues,并返回参数个数minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);}//对构造函数进行排序,先按方法修饰符排序:public排非public前面,再按构造函数参数个数排序:参数多的排前面AutowireUtils.sortConstructors(candidates);//比较差异值,用于构造器选择int minTypeDiffWeight = Integer.MAX_VALUE;Set> ambiguousConstructors = null;LinkedList causes = null;//遍历构造器for (Constructor candidate : candidates) {//获取构造器参数类型Class[] paramTypes = candidate.getParameterTypes();//如果已经确定好了构造器了,这里就跳过了,因为遍历的构造函数已经排过序,后面不会有更合适的候选者了if (constructorToUse != null && argsToUse != 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;}//如果参数个数小于最小参数个数,则不符合条件,跳过if (paramTypes.length < minNrOfArgs) {continue;}ArgumentsHolder argsHolder;if (resolvedValues != null) {try {// 解析使用ConstructorProperties注解的构造函数参数String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);if (paramNames == null) {//获取参数名称查找解析器ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();if (pnd != null) {//解析出构造器的参数名称paramNames = pnd.getParameterNames(candidate);}}//通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean)argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);}catch (UnsatisfiedDependencyException ex) {if (logger.isTraceEnabled()) {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.//如果当前遍历的构造函数参数个数与explicitArgs长度不相同,则跳过该构造函数if (paramTypes.length != explicitArgs.length) {continue;}//使用传递进来的值构建ArgumentsHolderargsHolder = new ArgumentsHolder(explicitArgs);}//根据mbd的解析构造函数模式(true: 宽松模式(默认),false:严格模式),// 将argsHolder的参数和paramTypes进行比较,计算paramTypes的类型差异权重值int typeDiffWeight = (mbd.isLenientConstructorResolution() ?argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));// Choose this constructor if it represents the closest match.//类型差异权重值越小,则说明构造函数越匹配,则选择此构造函数if (typeDiffWeight < minTypeDiffWeight) {//确定最终的构造器、参数值等constructorToUse = candidate;argsHolderToUse = argsHolder;argsToUse = argsHolder.arguments;minTypeDiffWeight = typeDiffWeight;ambiguousConstructors = null;}//如果存在两个候选者的权重值相同,并且是当前遍历过权重值最小的,因为有更小则会替换大的构造器else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {//添加到ambiguousConstructors中if (ambiguousConstructors == null) {ambiguousConstructors = new LinkedHashSet<>();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()) {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 && argsHolderToUse != null) {argsHolderToUse.storeCache(mbd, constructorToUse);}}Assert.state(argsToUse != null, "Unresolved constructor arguments");//实例化bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));return bw;}

首先会判断构造函数是否只有一个,并且是无参、没有参数值,则使用无参构造器创建实例。否则获取构造函数,按权限public排在非public前面,参数多的排在参数少的前面进行排序。解析看当前需要注入的参数有多少个,根据构造器参数不小于实际需要注入的参数个数进行过滤,根据不同的模式选择策略比较参数的权重,计算权重值越小,则构造器越符合要求,最后使用最终确定构造器进行创建。

这里方法比较巧妙的设计,第一次执行该方法选择构造器流程后,会将构造器、ArgumentsHolder等存储起来,如果是原型模式(多例),则每次获取对象都会获取,这样的好处是避免耗费系统性能,因为对于实例化过程而已,最终都是使用同个构造器。

resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues),见方法10详解
createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1),见方法12详解

根据例子进行DEBUG,比较好理解:

public class Address {String province;String city;public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}
}
public class Teacher implements Person {private String name;private String age;private Address address;public Teacher(String name, String age, Address address, List list) {this.name = name;this.age = age;this.address = address;}public Teacher(String name, String age, Address address) {this.name = name;this.age = age;this.address = address;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}@Overridepublic void work() {System.out.printf("我是:"+name+",今年:"+age+":工作中");}@Overridepublic void sleep() {}
}

zhudachang1zhudachang2zhudachang3

编写入口:

	public static void main(String[] args) {ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("application-context.xml");Teacher teacher = (Teacher) applicationContext.getBean("teacher");}

方法10:resolveConstructorArguments

private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();TypeConverter converter = (customConverter != null ? customConverter : bw);BeanDefinitionValueResolver valueResolver =new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);//设置xml配置的构造函数参数个数int minNrOfArgs = cargs.getArgumentCount();//遍历for (Map.Entry entry : cargs.getIndexedArgumentValues().entrySet()) {//获取xml配置的构造函数注入index的值int index = entry.getKey();if (index < 0) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Invalid constructor argument index: " + index);}//判断配置的下标值是否大于配置参数的个数if (index > minNrOfArgs) {minNrOfArgs = index + 1;}//获取需要注入的值ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();//判断是否解析过了,如果解析过则将下标跟注入值添加到resolvedValues中,if (valueHolder.isConverted()) {resolvedValues.addIndexedArgumentValue(index, valueHolder);}else {//将值进行转换封装创建,如 为BeanDefinition,进行实例化创建Object resolvedValue =valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());//将生成的对象进行封装ConstructorArgumentValues.ValueHolder resolvedValueHolder =new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());//设置原始值resolvedValueHolder.setSource(valueHolder);//添加到ConstructorArgumentValues的indexedArgumentValues集合中resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);}}//遍历其他类型注入方式for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {//判断是否完成转换if (valueHolder.isConverted()) {resolvedValues.addGenericArgumentValue(valueHolder);}else {//获取创建后的实例值Object resolvedValue =valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());//封装成ValueHolder 对象ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());//设置初始对象值resolvedValueHolder.setSource(valueHolder);//添加到ConstructorArgumentValues的genericArgumentValues集合中resolvedValues.addGenericArgumentValue(resolvedValueHolder);}}return minNrOfArgs;}

方法11:createArgumentArray

private ArgumentsHolder createArgumentArray(String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,BeanWrapper bw, Class[] paramTypes, @Nullable String[] paramNames, Executable executable,boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();TypeConverter converter = (customConverter != null ? customConverter : bw);//新建一个ArgumentsHolder来存放匹配到的参数ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);Set usedValueHolders = new HashSet<>(paramTypes.length);Set autowiredBeanNames = new LinkedHashSet<>(4);for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {//获取参数类型的class对象,如StringClass paramType = paramTypes[paramIndex];//获取该位置的参数名称String paramName = (paramNames != null ? paramNames[paramIndex] : "");// Try to find matching constructor argument value, either indexed or generic.ConstructorArgumentValues.ValueHolder valueHolder = null;if (resolvedValues != null) {//根据下标,参数名称、参数下标获取ValueHolder 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).//如果查询不到,则尝试使用可以进行类型之间转换的类型进行查询,如String -> intif (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!//添加到ValueHolder集合中usedValueHolders.add(valueHolder);//获取原始值Object originalValue = valueHolder.getValue();Object convertedValue;if (valueHolder.isConverted()) {//如果转换过,则直接进行赋值convertedValue = valueHolder.getConvertedValue();//添加到预选参数中args.preparedArguments[paramIndex] = convertedValue;}else {//将构造函数跟下标封装成MethodParameter MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);try {//将原始值转换成参数所需类型,转换失败则抛异常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) {Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();//标记为需要解析args.resolveNecessary = true;//添加sourceValue作为预备参数args.preparedArguments[paramIndex] = sourceValue;}}//将convertedValue作为args在paramIndex位置的参数args.arguments[paramIndex] = convertedValue;//将originalValue作为args在paramIndex位置的原始参数args.rawArguments[paramIndex] = originalValue;}else {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.//如果不是@Autowire注解的构造函数,则抛异常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 {//如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象// 例如:@Autowire修饰构造函数,自动注入构造函数中的参数bean就是在这边处理Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter, fallback);//设置原始值args.rawArguments[paramIndex] = autowiredArgument;//设置值args.arguments[paramIndex] = autowiredArgument;//设置预备值args.preparedArguments[paramIndex] = autowiredArgumentMarker;//标记为需要解析args.resolveNecessary = true;}catch (BeansException ex) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);}}}//依赖了其他的bean,则注册依赖关系for (String autowiredBeanName : autowiredBeanNames) {this.beanFactory.registerDependentBean(autowiredBeanName, beanName);if (logger.isDebugEnabled()) {logger.debug("Autowiring by type from bean name '" + beanName +"' via " + (executable instanceof Constructor ? "constructor" : "factory method") +" to bean named '" + autowiredBeanName + "'");}}return args;}

方法12:instantiateBean

	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {try {Object beanInstance;final BeanFactory parent = this;if (System.getSecurityManager() != null) {beanInstance = AccessController.doPrivileged((PrivilegedAction) () ->getInstantiationStrategy().instantiate(mbd, beanName, parent),getAccessControlContext());}else {//获取策略进行实例化beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);}//封装成BeanWrapper 对象BeanWrapper bw = new BeanWrapperImpl(beanInstance);//初始化设置BeanWrapper属性值initBeanWrapper(bw);return bw;}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);}}
 

getInstantiationStrategy().instantiate(mbd, beanName, parent),见方法13详解

方法13:instantiate

@Overridepublic Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {// Don't override the class with CGLIB if no overrides.if (!bd.hasMethodOverrides()) {Constructor constructorToUse;synchronized (bd.constructorArgumentLock) {//获取构造函数constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;if (constructorToUse == null) {//获取class对象final Class clazz = bd.getBeanClass();if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");}try {if (System.getSecurityManager() != null) {constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction>) clazz::getDeclaredConstructor);}else {//获取无参构造器constructorToUse = clazz.getDeclaredConstructor();}//设置无参构造器,下次实例化时可直接获取使用bd.resolvedConstructorOrFactoryMethod = constructorToUse;}catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);}}}//实例化return BeanUtils.instantiateClass(constructorToUse);}else {// Must generate CGLIB subclass.//使用cglib方式进行实例化return instantiateWithMethodInjection(bd, beanName, owner);}}

BeanUtils.instantiateClass(constructorToUse),见方法14详解

方法14:instantiateClass

public static  T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {Assert.notNull(ctor, "Constructor must not be null");try {//如果构造函数非Public,则设置Accessible权限ReflectionUtils.makeAccessible(ctor);//判断是否使用kotlin语言,如果是则使用kotlin语言进行实例化if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {return 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];//判断类型是否是基本数据类型,并尝试从默认类型中获取值//void、Integer、Double、Short、Long、Character、Byte、Boolean、FloatargsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);}else {//赋值给参数数组argsWithDefaultValues[i] = args[i];}}//实例化return ctor.newInstance(argsWithDefaultValues);}}catch (InstantiationException ex) {throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);}catch (IllegalAccessException ex) {throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);}catch (IllegalArgumentException ex) {throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);}catch (InvocationTargetException ex) {throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());}}

限于篇幅,下篇文章继续讲解实例化之后的流程。

总结

1、在实例构造函数实例化创建前,会调用InstantiationAwareBeanPostProcessor类型的postProcessBeforeInstantiation方法,并返回实例,如果实例不为空,则不会走后面的doCreateBean流程。

2、进入创建Bean环节,判断是否使用工厂方法或Supplier方式进行实例化,并返回实例。不满足上述两种创建过程,则会从bean的定义信息中查询是否有确定的构造器、注入参数等,有则直接使用确定的构造器及参数进行实例化。

3、通过后置器处理器SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法进行处理并返回符合条件的构造函数,如果bean的构造函数带有@Autowire注解或有且仅有一个带参的构造函数则返回。

4、使用autowireConstructor自动构造函数的方式进行创建时,如果没有传递构造函数数组,则会获取所有的构造函数数组,并对数据进行排序,过滤掉构造函数参数个数小于需要注入的参数个数。对注入参数进行转换,实例化创建等。如果没有传递参数、并且构造函数使用了@Autowire注解,则会尝试查询创建工厂中所匹配的对象。

5、使用无参构造函数进行实例化

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...