前言java
本文轉自「天河聊技術」微信公衆號spring
本次接着上次的介紹來解析bean初始化和依賴注入數組
正文微信
上一次跟蹤到這個方法app
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBeanless
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition.容許後處理器修改合併後的bean定義。 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { 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. 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"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); 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) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); 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.bean註冊爲一次性。 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
找到這行代碼ide
// 建立bean對象 instanceWrapper = createBeanInstance(beanName, mbd, args);
進入到這個方法函數
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstancepost
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. Class<?> beanClass = resolveBeanClass(mbd, beanName); // 類必須是public,構造方法必須是public 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<?> 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); } } // Need to determine the constructor... Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { // 構造參數注入 return autowireConstructor(beanName, mbd, ctors, args); } // No special handling: simply use no-arg constructor.無需特殊處理:只需使用無arg構造函數。 return instantiateBean(beanName, mbd); }
找到這一行代碼ui
// 若是工廠方法不爲空,就用工廠方法建立bean if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); }
優先使用工廠方法建立bean對象
進入這個方法
org.springframework.beans.factory.support.ConstructorResolver#instantiateUsingFactoryMethod
這一行代碼
// 默認類型自動裝配,判斷是不是構造參數裝配 boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
找到這一行代碼
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
執行工廠方法建立對象
返回到這個方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance這一行代碼
構造方法注入 return autowireConstructor(beanName, mbd, null, null);
進入這個方法
org.springframework.beans.factory.support.ConstructorResolver#autowireConstructor
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd, @Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw); Constructor<?> constructorToUse = null; ArgumentsHolder argsHolderToUse = null; Object[] argsToUse = null; 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) { // 解析bean定義中的方法 argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve); } } if (constructorToUse == null) { // Need to resolve the constructor.判斷是不是構造參數注入 boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null; int minNrOfArgs; if (explicitArgs != null) { minNrOfArgs = explicitArgs.length; } else { ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); // 解析構造參數 minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } // Take specified constructors, if any.使用指定的構造函數(若是有的話)。 Constructor<?>[] candidates = chosenCtors; if (candidates == null) { 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); } } AutowireUtils.sortConstructors(candidates); int minTypeDiffWeight = Integer.MAX_VALUE; Set<Constructor<?>> ambiguousConstructors = null; LinkedList<UnsatisfiedDependencyException> causes = null; for (Constructor<?> candidate : candidates) { Class<?>[] paramTypes = candidate.getParameterTypes(); 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; } 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); } } // 解析構造參數並轉換成數組 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. if (paramTypes.length != explicitArgs.length) { continue; } argsHolder = new ArgumentsHolder(explicitArgs); } 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) { 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.storeCache(mbd, constructorToUse); } } try { // bean初始化策略,若是容器中bean方法須要被覆蓋,採用cglib建立子類 final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy(); Object beanInstance; if (System.getSecurityManager() != null) { final Constructor<?> ctorToUse = constructorToUse; final Object[] argumentsToUse = argsToUse; beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> // 初始化bean strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse), beanFactory.getAccessControlContext()); } else { beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse); } bw.setBeanInstance(beanInstance); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean instantiation via constructor failed", ex); } }
返回到這個方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
使用默認構造參數初始化bean return instantiateBean(beanName, mbd);
進入這個方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#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<Object>) () -> // 獲取bean初始化策略並進行初始化 getInstantiationStrategy().instantiate(mbd, beanName, parent), getAccessControlContext()); } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
獲取bean初始化策略並進行初始化 getInstantiationStrategy().instantiate(mbd, beanName, parent),
進入這個方法
org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)
@Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides.若是沒有重寫,不要使用CGLIB覆蓋該類。 if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { 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<Constructor<?>>) 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); } }
返回到這個方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean這一行代碼
// 填充依賴注入的bean對象 populateBean(beanName, mbd, instanceWrapper);
進入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean這個方法
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // 若是是按名稱注入或者按類型注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable.若是能夠的話,在autowire的基礎上添加屬性值。 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { // 按名稱注入 autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable.若是能夠的話,按類型添加基於autowire的屬性值。 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { // 按類型注入 autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
找到這行代碼
// 按類型注入 autowireByType(beanName, mbd, bw, newPvs);
進入這個方法org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByType
protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. if (Object.class != pd.getPropertyType()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance()); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 解析依賴值 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
找到這行代碼
解析依賴值 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
進入這個方法
org.springframework.beans.factory.support.DefaultListableBeanFactory#createOptionalDependency
private Optional<?> createOptionalDependency( DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) { DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) { @Override public boolean isRequired() { return false; } @Override public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) { return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) : super.resolveCandidate(beanName, requiredType, beanFactory)); } }; // 解析依賴 return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null)); }
本次介紹到這裏,下次繼續。
最後
本次介紹到這裏,以上內容僅供參考。