交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
spring核心第4 章:BeanFactory
分享
未结
0
883
李延
LV6
2021-05-13
悬赏:20积分
## 作用 提供getBean方法。可以获取所有spring的bean对象。 整体实现功能为 通过BeanDefinitionRegistry提供bean定义。并且通过BeanDefinition创建、初始化、解决依赖注入bean对象。将单例对象保存在SingletonBeanRegistry中。 ## 主要子类 接口的主要实现是DefaultListableBeanFactory ## 继承关系  ### BeanFactory 定义了各种getBean 的方法 ### ListableBeanFactory 可列举的BeanFactory 定义了批量获取bean的方法。比如可以一次获取全部的bean(太暴力了),根据类型获取bean. ### HierarchicalBeanFactory 定义父BeanFactory ### ConfigurableBeanFactory 可配置的BeanFactory。其中可配置的内容有: BeanExpressionResolver ConversionService PropertyEditorRegistrar TypeConverter StringValueResolver BeanPostProcessor ### AutowireCapableBeanFactory 可以自动注入的BeanFactory。定义了与自动装配相关的接口 ### FactoryBeanRegistrySupport 是FactoryBeanRegistrySupport的扩展 其中添加成员变量 ```java private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16); ``` 将所有通过FactoryBean的get方法获取到的单例对象保存在这里,提供使用 ### AbstractBeanFactory BeanFactory的抽象实现,其中主要实现的有ConfigurableBeanFactory的所有方法,和部分getBean方法。 下面主要讲解getBean的方法 #### getBean ```java @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); } ``` 我们可以看到所有的getBean方法最终都调用了doGetBean方法 #### doGetBean ```java protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { //去除 & ,转换别名 String beanName = transformedBeanName(name); Object bean; // 尝试从单例中获取对象 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } //可以获取到对象是调用getObjectForBeanInstance,解决FactoryBean相关问题 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 判断当前bean是否正在创建。 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 尝试从父容器中获取 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } //到这一步说明,当前bean还没有被创建。这个时候就需要获取BeanDefinition,并创建bean StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate") .tag("beanName", name); try { if (requiredType != null) { beanCreation.tag("beanType", requiredType::toString); } //融合bean定义。这一步是将父定义与当前定义进行融合 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 获取依赖,优先初始化依赖。可以通过@DependsOn来定义依赖 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //注册依赖,将bean的依赖关系保存在dependentBeanMap成员变量中 registerDependentBean(dep, beanName); try { //先初始化依赖 getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // 如果是单例通过createBean 方法初始化bean,并通过getSingleton 注册。 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //如果是多例,就只调用createBean else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'"); } Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { //其他情况,将其保存在对应的Scope 中。 Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new ScopeNotActiveException(beanName, scopeName, ex); } } } catch (BeansException ex) { beanCreation.tag("exception", ex.getClass().toString()); beanCreation.tag("message", String.valueOf(ex.getMessage())); cleanupAfterBeanCreationFailure(beanName); throw ex; } finally { beanCreation.end(); } } //如果有需要,尝试类型转换 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; } ``` 整体过程我们可以看到如下步骤: * 1、获取真实的bean 名称 :(1)去除 & ,转换别名 * 2、调用 getSingleton 。尝试获取bean对象。 {@linkplain DefaultSingletonBeanRegistry#getSingleton(String)} * 2.1 可以获取到bean 时,调用getObjectForBeanInstance 解析见:{@linkplain AbstractBeanFactoryStu#getObjectForBeanInstance()} * 3、通过 {@linkplain AbstractBeanFactory#isPrototypeCurrentlyInCreation(String)} 判断bean 是否真正创建。应该是构造函数的循环依赖判断 * 4、去父beanFacory尝试获取,详细不解析了 * 5、合并bean的父定义。生成新的完整bean定义。 * 6、优先初始化依赖bean //@DependsOn 与 xml中的depends-on 属性。 * 7、对于不同范围的做不同的处理, * 7.1、单例:如果是单例通过createBean 方法初始化bean,并通过getSingleton 注册。 * 7.2、多例:如果是多例,就只调用createBean。 * 8、如果有需要,尝试类型转换。使用 TypeConverter 对象 总结来说: doGetBean完成了所以关于bean 获取的内容。当无法获取到bean是,调用createBean。将bean的创建过程留给子类实现。 #### getObjectForBeanInstance 在dogetBean方法中,在获取到bean对象后,都调用此方法,判断是获取BeanFactory对象本身,还是BeanFactory的get对象。 * 1、判断是否以 & 开头。如果是 FactoryBean 子类,直接返回,也就是 &取出来的是bean工厂 * 2、如果不是以 & 开头,不是 FactoryBean 子类,直接返回。 * 3、调用{@linkplain FactoryBeanRegistrySupport#getCachedObjectForFactoryBean(String)} 获取缓存的 真实bean * 获取不到时{@linkplain FactoryBeanRegistrySupport#getObjectFromFactoryBean(FactoryBean, String, boolean)}调用getBean获取真实bean。 ### AbstractAutowireCapableBeanFactory 该类除了实现了AbstractBeanFactory 的createBean方法外,还实现了AutowireCapableBeanFactory的相关方法。 #### createBean ```java //去掉不重要的代码。可以看到在创建对象前,调用了resolveBeforeInstantiation 方法,若有bean返回,则直接使用返回的bean,否则继续调用doCreateBean 方法创建对象。 @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; } ``` #### resolveBeforeInstantiation ```java @Nullable 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. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //迭代调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,若返回不未null,则直接使用返回的对象 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; } ``` #### doCreateBean 在createBean方法中,对象的创建是委托给本方法来实现的,具体代码如下: ```java protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } //创建bean对象 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // 对应merged bean 执行 postProcessMergedBeanDefinition 方法 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; } } // 将新new出来的对象,以ObejctFactory形式保存在singletonFactory中 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"); } 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 " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } ``` 对于上面代码我们可以看到一下步骤: 1、通过createBeanInstance(beanName, mbd, args); 创建出来对象。 2、将新new出来的对象,以ObejctFactory形式保存在singletonFactory中。这里以ObejctFactory对象是因为如果对象被提取取出将会执行对应的后置处理器。 3、填充属性 4、执行初始化方法 接下来我们将具体分析这几步的具体内容。 #### createBeanInstance ```java 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); 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 来创建对象 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //对于有MethodName 使用 Method方法创建对象,在使用中就是我们用的@Bean注解 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } //接下来都是对于应该使用那种个构造函数的判断。 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); } } // 调用后置处理器确定使用哪个构造函数 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); 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); } ``` 通过上面代码我们可以看到对于创建bean一共进行了以下的步骤: 1、尝试使用instanceSupplier 创建对象 2、尝试使用MethodName 创建对象 3、不是上述方法创建对象是,使用反射的方法创建对象。 3.1、通过benaProcessor判断使用哪个构造函数来创建。 3.2、对于无指定构造函数时调用autowireConstructor 3.3、其他情况调用instantiateBean 下面对于这几步我们相信介绍。 ##### MethodName 方式创建 在我们平常使用的 @Bean 注解就是使用的这种方式创建对象,下面是一个测试用例: ```java @Component public class BeanParser { @Bean public BeanOnBeanTest beanOnBeanTest(){ return new BeanOnBeanTest(); } public static class BeanOnBeanTest{ } } ```  我们可以看到通过@Bean 方法。当前bean的factoryMethodName方法就是我们指定的beanOnBeanTest。我们跟进源码查看 ```java protected BeanWrapper instantiateUsingFactoryMethod( String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) { return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); } ``` 这里直接调用的是ConstructorResolver 方法。具体我们在起对应章节说明。 ##### 构造函数的选择 determineConstructorsFromBeanPostProcessors 前面章节我们通过调用determineConstructorsFromBeanPostProcessors 方法确定构造函数。代码如下: ```java @Nullable protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException { if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) { //遍历所有的SmartInstantiationAwareBeanPostProcessor类型的BeanPostProcessor,如果返回值不为空则返回内容,如果为空则返回null。 for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) { Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName); if (ctors != null) { return ctors; } } } return null; } ``` 我们可以看到spring通过后置处理器来确定是否有指定的构造函数。而在默认的后置处理器中具体干了以下事情: AutowiredAnnotationBeanPostProcessor 类 1、筛选出构造函数中包含Autowired和Value 注解 2、对于没有无参的构造函数时,选择出合适的构造函数 具体关于AutowiredAnnotationBeanPostProcessor 内容的解析可以看对应章节内容 ##### autowireConstructor 当通过上一章节,我们指定了构造函数时,调用当前方法创建对象,代码如下: ```java protected BeanWrapper autowireConstructor( String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) { return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs); } ``` 我们可以看到直接调用了ConstructorResolver 方法来创建对象,其代码在对应章节说明 ##### instantiateBean 午参的构造函数 当我们需要使用无参的构造函数时,调用当前方法。 ```java protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { try { Object beanInstance; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged( (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this), getAccessControlContext()); } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } } ``` 在这里我们看到首先spring通过InstantiationStrategy 创建出对象,并且将其封装导BeanWrapper中。其中InstantiationStrategy默认使用的是CglibSubclassingInstantiationStrategy,对于这一点不再详细解析。 **到目前这一步,我们解析完成了对象create的过程。解析来解析剩余过程** #### getEarlyBeanReference 在doCreateBean代码中。create完对象后后被封装为ObjectFactory对象保存起来 ```java addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); ``` 其中addSingletonFactory 方法我们在DefaultSingletonBeanRegistry类中进行了说明。而getEarlyBeanReference又做了什么事情,代码如下: ```java protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) { exposedObject = bp.getEarlyBeanReference(exposedObject, beanName); } } return exposedObject; } ``` 当当前的bean还没有初始化完成,但就被其他bean依赖时,我们就需要通过singletonFactory.getObject() 提前返回当前对象。而此时,我们其实需要的不是这个对象本身而是它的代理,这个时候就需要通过后置处理器的getEarlyBeanReference方法返回它的代理了。这一点在aop中可以体现。 #### populateBean 填充属性 populateBean方法就是对bean的方法和自动的填充,具体代码如下: ```java 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. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); //判断属性注入的类型 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; //使用后置处理器获取需要注入的对象 if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } //注入属性 if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } } ``` 上面的代码共分为3步: 1、判断当前bean的byName还是byType。在springboot中,这部分代码无效。不做解析。 2、通过后置处理器注入属性,其中包括Autowired和Value 注解。这一点我们将在后置处理器中说明。 3、将前面两部分的属性注入到bean中。(下面的章节) **这些就是关于属性注入的内容。下面将介绍初始化的内容** #### initializeBean 初始化 执行bean的初始化方法及其在初始化前后的后者处理器。具体如下: ```java protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { //如果是Aware子类,则注入对应的属性 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; //执行BeforeInitialization方法 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } //执行初始化方法,2种形式。1、BeforeInitialization的子类;2、指定了对应的初始化方法 try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } //执行AfterInitialization方法 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } ``` **到目前为止**。我们解析完成了对象创建的过程。 ### DefaultListableBeanFactory 在这个类中,bean的创建其父类已经实现。在这里主要说明的有2个方法。 1、通过class类型getBean 2、AutowireCapableBeanFactory 的resolveDependency实现 #### getBean 根据class 获取bean ```java @Override public <T> T getBean(Class<T> requiredType) throws BeansException { return getBean(requiredType, (Object[]) null); } @SuppressWarnings("unchecked") @Override public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException { Assert.notNull(requiredType, "Required type must not be null"); Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false); if (resolved == null) { throw new NoSuchBeanDefinitionException(requiredType); } return (T) resolved; } ``` 我们可以看到最终是将class转换未Resolvable对象调用resolveBean #### resolveBean ```java @Nullable private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) { //通过resolveNamedBean 方法获取 NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull); if (namedBean != null) { return namedBean.getBeanInstance(); } //在父类中获取 BeanFactory parent = getParentBeanFactory(); if (parent instanceof DefaultListableBeanFactory) { return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull); } //通过ObjectProvider 获取 else if (parent != null) { ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType); if (args != null) { return parentProvider.getObject(args); } else { return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable()); } } return null; } private <T> NamedBeanHolder<T> resolveNamedBean( ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException { Assert.notNull(requiredType, "Required type must not be null"); String[] candidateNames = getBeanNamesForType(requiredType); //多于一个候选时,尝试使用AutowireCandidate确定唯一 if (candidateNames.length > 1) { List<String> autowireCandidates = new ArrayList<>(candidateNames.length); for (String beanName : candidateNames) { if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) { autowireCandidates.add(beanName); } } if (!autowireCandidates.isEmpty()) { candidateNames = StringUtils.toStringArray(autowireCandidates); } } //候选确定时,直接返回 if (candidateNames.length == 1) { String beanName = candidateNames[0]; return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args)); } else if (candidateNames.length > 1) { Map<String, Object> candidates = CollectionUtils.newLinkedHashMap(candidateNames.length); for (String beanName : candidateNames) { if (containsSingleton(beanName) && args == null) { Object beanInstance = getBean(beanName); candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance)); } else { candidates.put(beanName, getType(beanName)); } } //通过isPrimary来确定 String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass()); if (candidateName == null) { //通过优先度确认 candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass()); } if (candidateName != null) { Object beanInstance = candidates.get(candidateName); if (beanInstance == null || beanInstance instanceof Class) { beanInstance = getBean(candidateName, requiredType.toClass(), args); } return new NamedBeanHolder<>(candidateName, (T) beanInstance); } if (!nonUniqueAsNull) { throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet()); } } return null; } ``` 上面对于bean获取分为以下几步: 1. 排除autowireCandidate 为false的对象。@Bean(autowireCandidate = false),参考:[https://blog.csdn.net/likun557/article/details/104438417](https://blog.csdn.net/likun557/article/details/104438417) 2. 候选对象唯一时,直接返回 3. 选包含 @Primary 的bean优先注入。参考[https://blog.csdn.net/likun557/article/details/104404333](https://blog.csdn.net/likun557/article/details/104404333) 4. 判断优先级,返回优先级高的 #### resolveDependency 该方法主要是用于解决spring的依赖问题。比如:我们通过注解@Autowired或者@Value在自动和方法上的自动注入都是通过当前方法 ##### 示例 下面两个类分别是通过@Value和@Autowired注入相关内容: ```java @Component public class HaveBeanPaulateBean { @Autowired @Qualifier("notPapulateBean") private NotPapulateBean notPapulateBean; public NotPapulateBean getNotPapulateBean() { return notPapulateBean; } public void setNotPapulateBean(NotPapulateBean notPapulateBean) { this.notPapulateBean = notPapulateBean; } } @Component public class HaveValuePaulateBean { @Value("1") private int a; @Value("字符串测试") private String b; @Value("${spring.datasource.username}") private String c; } ``` 通过dubug我们可以看到下图内容:   ##### 源码说明 ```java /** * 参数说明: * descriptor 对于需要注入的 字段或者方法 统一的封装描述 * requestingBeanName 被注入对象class的bean名称 * autowiredBeanNames 注入目标的bean名称 * typeConverter 数据类型转换器 * */ @Override @Nullable public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { //为descriptor 设置 ParameterNameDiscoverer 对象 descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); //对于特殊类型的数据进行不同的处理。 if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } } ``` 上面代码共分为以下几步: 1、为descriptor 设置 ParameterNameDiscoverer 对象 2、不同的数据类型分为不同情况处理 3、所有类型,最终都会调用到doResolveDependency方法中 我们继续跟进doResolveDependency方法 ```java @Nullable public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { //通过resolveShortcut提取获取对象,一般是一个空实现,没有作用。 Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } //获取目标的class Class<?> type = descriptor.getDependencyType(); //通过AutowireCandidateResolver对象解决@Value注入情况 Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { //如果是字符串,通过StringValueResolver 解决 ${}占位符问题。 if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } //如果有需要通过TypeConverter 转换类型 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); try { return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); } catch (UnsupportedOperationException ex) { // A custom TypeConverter which does not support TypeDescriptor resolution... return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } } //处理集合情况。比如:数组、Collection、Map等类型 Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } //通过findAutowireCandidates 获取到所有匹配的情况 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); //如果是必须的情况,抛出异常,否则返回null if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; //有多个匹配值时通过determineAutowireCandidate 方法确定唯一值。 if (matchingBeans.size() > 1) { autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(descriptor.getResolvableType(), 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; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } //只有一个时,返回确定的那个值。 else { // We have exactly one match. Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { 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); } } ``` 整体来说逻辑如下: 对于@Value注解: 1、通过AutowireCandidateResolver对象解决@Value注入的值 2、如果是字符串,通过StringValueResolver 解决 ${}占位符问题。 3、如果有需要通过TypeConverter 转换类型 对于@AutoWired注解: 1、调用 resolveMultipleBeans 方法处理集合情况包括:数组、Collection、Map等类型 2、通过findAutowireCandidates 方法返回所有查询到的对象 3、当只有几个结果的时候直接返回 4、当有多个结果的时候通过determineAutowireCandidate 方法确定唯一 上面的内容中AutowireCandidateResolver、StringValueResolver 、TypeConverter 说明将在其具体的文档中解析,下面不做详细说明我们主要关注点在 resolveMultipleBeans、findAutowireCandidates、determineAutowireCandidate 方法中。 resolveMultipleBeans 处理对象为集合的情况比如:数组、Collection、Map等类型 ```java @Nullable private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) { Class<?> type = descriptor.getDependencyType(); if (descriptor instanceof StreamDependencyDescriptor) { Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } Stream<Object> stream = matchingBeans.keySet().stream() .map(name -> descriptor.resolveCandidate(name, type, this)) .filter(bean -> !(bean instanceof NullBean)); if (((StreamDependencyDescriptor) descriptor).isOrdered()) { stream = stream.sorted(adaptOrderComparator(matchingBeans)); } return stream; } else if (type.isArray()) { Class<?> componentType = type.getComponentType(); ResolvableType resolvableType = descriptor.getResolvableType(); Class<?> resolvedArrayType = resolvableType.resolve(type); if (resolvedArrayType != type) { componentType = resolvableType.getComponentType().resolve(); } if (componentType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType); if (result instanceof Object[]) { Comparator<Object> comparator = adaptDependencyComparator(matchingBeans); if (comparator != null) { Arrays.sort((Object[]) result, comparator); } } return result; } else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric(); if (elementType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (result instanceof List) { if (((List<?>) result).size() > 1) { Comparator<Object> comparator = adaptDependencyComparator(matchingBeans); if (comparator != null) { ((List<?>) result).sort(comparator); } } } return result; } else if (Map.class == type) { ResolvableType mapType = descriptor.getResolvableType().asMap(); Class<?> keyType = mapType.resolveGeneric(0); if (String.class != keyType) { return null; } Class<?> valueType = mapType.resolveGeneric(1); if (valueType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { return null; } } ``` 我们可以看到,通过不太情况的判断,最终都是通过findAutowireCandidates 获取bean对象,然后做的各自分装。 findAutowireCandidates 获取所有符合要求的依赖对象。 ```java protected Map<String, Object> findAutowireCandidates( @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { //通过类型获取所有依赖,最终调用的是getBeanNamesForType 方法上面章节有说明 String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); //结果的候选集 Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length); //优先处理resolvableDependencies内的类型 for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) { Class<?> autowiringType = classObjectEntry.getKey(); if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = classObjectEntry.getValue(); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } //循环所有候选情况通过isAutowireCandidate判断是否符合要求,并通过addCandidateEntry 添加对象 for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty()) { boolean multiple = 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) && (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty() && !multiple) { // 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; } ``` 到这一步我们可以看到: 1. 首先通过类型获取所有依赖。 2. 之后优先处理特殊类:resolvableDependencies集合的内容。 3. 再通过isAutowireCandidate 方法当前类是否符合要求,其中@Qualifier注解就在这一步进行筛选。 4. 最后通过addCandidateEntry 获取对象并添加到候选集中。 对于isAutowireCandidate 方法最终会调用:AutowireCandidateResolver的 isAutowireCandidate方法。我们在器进行解析 对于addCandidateEntry则是调用beanFactory.getBean(beanName) 不再详细解析 目前就剩下最后的 determineAutowireCandidate方法多个返回值时确定需要的内容。其实后调用 determinePrimaryCandidate 方法。我们在上面的解析中也做了说明。
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号