详解beanFactory.getBeanNamesForType

@Override
	public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
		// 如果beanFactory中的beanDefinitons没有被冻结 || 给定类型为null || 允许初始化factoryBean创建的对象或者懒加载的对象
		if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
			return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
		}
		// 值得注意的是,不管type是否为空,allowEagerInit是否为true
		// 只要isConfigurationFrozen()为false,就一定不会走这里
		// 因为isConfigurationFrozen()为false表示BeanDefinition可能还会发生更改或添加,所以不能进行缓存
		// 如果允许非单例的bean,那么从保存所有bean的集合中获取,否则从单例bean中获取
		Map<Class<?>, String[]> cache =
				(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
		String[] resolvedBeanNames = cache.get(type);
		if (resolvedBeanNames != null) {
			return resolvedBeanNames;
		}
		// 如果缓存中没有找到,那么只能重新获取,获取到之后放入缓存
		resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
		if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
			cache.put(type, resolvedBeanNames);
		}
		return resolvedBeanNames;
	}
	// 通过给性类型获取beanName,ResolvableType将原始类型进行了包装
	private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
		List<String> result = new ArrayList<>();
		// 检查所有的beanDefinition,匹配type
		// 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.
			// 如果beanName没有被定义为其他bean的别名则往下走,如果是别名则跳过(这个集合会保存所有的主beanName,并不会保存别名,别名有BeanFactory中别名map维护)
			if (!isAlias(beanName)) {
				try {
					// 获取合并的BeanDefinition,合并的BeanDefinition是指spring整合了父BeanDefinition的属性,将其他类型的BeanDefinition变成了RootBeanDefinition
					RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
					// 抽象的BeanDefiniton不做考虑,抽象的就是拿来继承的
					// 如果允许早期初始化,那么直接短路,进入方法体
					// 如果过不允许早期初始化,那么需要进一步判断,如果过是不允许早期初始化,并且beanClass已经加载或者他是可以早期初始化的,
					// 那么如果当前bean是工厂bean,并且制定的bean又是工厂
					// 那么这个bean就必须被早期初始化,也就是说不符合我们制定的allowEagerInit为false的情况,直接跳过
					// Only check bean definition if it is complete.仅在完成时检查 bean 定义
					// mbd不是abstract && (不是懒加载提前初始化 || (mbd的beanClass不为空 || mbd不是懒加载 || 允许懒加载 )) && 指定的 bean 不需要立即初始化以确定其类型)

					// 1. mbd不是抽象的 并且 允许早期初始化
					// 2. mbd不是抽象的 并且 mbd的beanClass已加载或者可以提前初始化 并且 不是工厂bean
					if (!mbd.isAbstract() && (allowEagerInit ||
							(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
									// (factoryBeanName != null && isFactoryBean(factoryBeanName) && !containsSingleton(factoryBeanName))
									!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
						// 判断bean是否为FactoryBean  FactoryBean.class.isAssignableFrom(beanType))
						boolean isFactoryBean = isFactoryBean(beanName, mbd);
						// // beanDefinition
						//	private final BeanDefinition beanDefinition;
						//	// bean名称
						//	private final String beanName;
						//	// bean别名数组
						//	@Nullable
						//	private final String[] aliases;
						BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
						boolean matchFound = false;
						// 如果过允许提前初始化或者singletonObjects中包含了beanName,则允许FactoryBean初始化
						boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
						// 如果decoratedDefinition不为null 并且 mbd不允许懒初始化,则没有被懒修饰
						boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());
						if (!isFactoryBean) {// 如果不是factoryBean
							// 如果包含非单例
							if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
								// 1. 如果不是factoryBean,并且 包含非单例
								// 2. 不是factoryBean, 并且 beanName是单例
								// 如果以上两个条件满足其中一个,则走isTypeMatch方法,判断beanName与type是否匹配
								matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
							}
						}
						else {
							if (includeNonSingletons || isNonLazyDecorated ||
									(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
								// 1. 如果是factoryBean,并且包含非单例
								// 2. 是factoryBean,并且 非懒加载
								// 3. 是factoryBean,并且 允许fanctoryBean早期初始化 并且beanName有对应单例,
								// 满足以上三个条件中的一个,则走isTypeMatch方法,判断beanName是否匹配
								matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
							}
							// 如果过beanName与type不匹配,则将beanName变为&beanName,走isTypeMatch方法,重新判断&beanName是否与type匹配
							if (!matchFound) {
								// In case of FactoryBean, try to match FactoryBean instance itself next.
								beanName = FACTORY_BEAN_PREFIX + beanName;
								matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
							}
						}
						// 如果beanName与指定类型相匹配,则将beanName放入结果集
						if (matchFound) {
							result.add(beanName);
						}
					}
				}
				catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
					if (allowEagerInit) {
						throw ex;
					}
					// Probably a placeholder: let's ignore it for type matching purposes.
					LogMessage message = (ex instanceof CannotLoadBeanClassException ?
							LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
							LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName));
					logger.trace(message, ex);
					// Register exception, in case the bean was accidentally unresolvable.
					onSuppressedException(ex);
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Bean definition got removed while we were iterating -> ignore.
				}
			}
		}

		// 检查手动注册的单例名称set,判断beanName是否与type对应
		// 比如environment就是在启动容器的时候硬编码注入的实例
		// Check manually registered singletons too.
		for (String beanName : this.manualSingletonNames) {
			try {
				// In case of FactoryBean, match object created by FactoryBean.
				if (isFactoryBean(beanName)) {
					// 1. beanName是factoryBean,并且 包含非单例 并且isTypeMatch判断beanName与type相匹配
					// 2. beanName是factoryBean,并且beanName为单例,并且isTypeMatch判断beanName与type相匹配,则将beanName加入结果
					if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
						result.add(beanName);
						// Match found for this bean: do not match FactoryBean itself anymore.
						continue;
					}
					// 以上不满足,则将beanName变为&beanName
					// In case of FactoryBean, try to match FactoryBean itself next.
					beanName = FACTORY_BEAN_PREFIX + beanName;
				}
				// 如果原生bean实例与type相匹配或者原生factoryBean与type相匹配,则加入结果
				// Match raw bean instance (might be raw FactoryBean).
				if (isTypeMatch(beanName, type)) {
					result.add(beanName);
				}
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Shouldn't happen - probably a result of circular reference resolution...
				logger.trace(LogMessage.format(
						"Failed to check manually registered singleton with name '%s'", beanName), ex);
			}
		}
		// 返回与type相匹配的beanName字符串数组
		return StringUtils.toStringArray(result);
	}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值