在分析spring容器的创建过程中分析了bean的创建过程。由于创建过程步骤还是比较多的于是就新开一篇博客来详细分析下beanFactory的getBean方法做了哪些操作。分析的是通过beanType获取bean,因为根据type获取其实最终调用的也是根据beanName获取bean。
这个方法的目的是根据类型获取beanNames:
先从缓存中获取该类型的所有beanName。
如果1没有获取到执行doGetBeanNamesForType:
manualSingletonNames
(容器创建时无参构造函数初始化的bean)中获取符合的单例bean和单例bean工厂对象。(这边要注意在返回工厂bean名称时需要加上 &
) 将获取的beanNames放入缓存中。
@Primary
信息。如果只有一个beanName的定义信息被注册到该beanFactory或者该beanFactory的 parentBeanFactory
中 并且该beanName的定义信息为Primary。返回该beanName。 @Priority
的优先级代号(数字越小优先级越高),返回优先级最高的bean名称。 resolveNamedBean的操作源码:
//if not allow cache all bean or allowEagerInit ? 这个条件看不懂 //isConfigurationFrozen if is true mean this context init finish //get bean name from beanDefinitionNames and manualSingletonNames if (!isConfigurationFrozen() || type == null || !allowEagerInit) { return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit); } // if allow cache all bean get bean name from cache first(isConigurationFrozen is true) Map<Class<?>, String[]> cache = // includeNonSingletons : 是否包含非单例对象 (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType); String[] resolvedBeanNames = cache.get(type); if (resolvedBeanNames != null) { return resolvedBeanNames; } // if can not get this bean type from cache ,get bean name from beanDefinitionNames and manualSingletonNames resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true); // here is some safe check: such as whether or not this bean classLoader to the beanFatory classLoader(具体我也不太清楚) if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) { cache.put(type, resolvedBeanNames); // put this beanname to cache } return resolvedBeanNames; 复制代码
doGetBeanNamesForType
操作源码:
List<String> result = new ArrayList<>(); // Check all bean definitions. for (String beanName : this.beanDefinitionNames) { // Only consider bean as eligible if the bean name // is not defined as alias for some other bean. if (!isAlias(beanName)) { try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // Only check bean definition if it is complete. if (!mbd.isAbstract() && (allowEagerInit || (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) && !requiresEagerInitForType(mbd.getFactoryBeanName()))) { // In case of FactoryBean, match object created by FactoryBean. boolean isFactoryBean = isFactoryBean(beanName, mbd); BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); boolean matchFound = (allowEagerInit || !isFactoryBean || (dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) && (includeNonSingletons || (dbd != null ? mbd.isSingleton() : isSingleton(beanName))) && isTypeMatch(beanName, type); if (!matchFound && isFactoryBean) { // In case of FactoryBean, try to match FactoryBean instance itself next. beanName = FACTORY_BEAN_PREFIX + beanName; matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type); } if (matchFound) { result.add(beanName); } } } catch (CannotLoadBeanClassException ex) { } catch (BeanDefinitionStoreException ex) { } } } // Check manually registered singletons too. for (String beanName : this.manualSingletonNames) { try { // In case of FactoryBean, match object created by FactoryBean. if (isFactoryBean(beanName)) { if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) { result.add(beanName); // Match found for this bean: do not match FactoryBean itself anymore. continue; } // In case of FactoryBean, try to match FactoryBean itself next. beanName = FACTORY_BEAN_PREFIX + beanName; } // Match raw bean instance (might be raw FactoryBean). if (isTypeMatch(beanName, type)) { result.add(beanName); } } catch (NoSuchBeanDefinitionException ex) { } } return StringUtils.toStringArray(result); 复制代码
该方法通过beanName获取bean,实际操作在 doGetBean
方法中:
&
),之后调用 getSingleton
试图获取bean实例:
getSingleton
未获取到。将bean置为创建状态。之后创建bean,创建过程将bean分成了单例,多例和其他三种情况来创建。 调用来获取bean对象。遍历BeanPostProcessors如果是InstantiationAwareBeanPostProcessor接口调用处理器的postProcessBeforeInstantiation来获取对象,如果获取到了则调用处理器的postProcessAfterInitialization获取对象,并返回。
如果resolveBeforeInstantiation未获取到对象使用doCreateBean创建对象:
populateBean
方法。不对bean进行初始化修改。 @Autowired
和 @Value
的属性,取出之前缓存的该对象InjectionMetadata,调用inject来设置 @Autowired
依赖属性(期间调用doResolveDependency来获取真正需要注入的属性)。 @Priority
整个bean的创建和初始化过程还是相当繁琐的步骤。bean的整个生命周期还是比较多样的,有很多BeanPostProcessor在bean创建前后以及初始化过程中都对bean进行了管理,包括bean全部创建后还有着回调功能,有着丰富的拓展功能。讲得可能不明了,希望对大家有所帮助。详细的demo可以去看博主的 github 。