在分析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 。