spring系列3-IOC的实现初探

目录

1. IOC发生的时间

2. XmlBeanFactory的UML

3. getBean方法的主要逻辑

参考资料


1. IOC发生的时间

一般情况,依赖注入发生在第一次向容器(BeanFactory或ApplicationContext)索要bean时,即调用getBean方法。

特别情况,通过设置bean的lazy-init属性=false执行预实例化,与一般情况相比,只是发生的时间不同,还是通过getBean方法触发。

2. XmlBeanFactory的UML

DefaultSingletonBeanRegistry类的几个重要属性:

Map<String, Object> singletonObjects(一级缓存):单例对象的缓存

Map<String, Object> earlySingletonObjects(二级缓存):早期(early)单例对象的缓存

Map<String, ObjectFactory<?>> singletonFactories(三级缓存):单例工厂的缓存

Set<String> singletonsCurrentlyInCreation:当前在创建中的单例bean name

FactoryBeanRegistrySupport类的缓存属性:

Map<String, Object> factoryBeanObjectCache:键是factoryBean name,值是factoryBean创建的对象

3. getBean方法的主要逻辑

scope=singleton时,逻辑如下:

byType装配依赖的逻辑较为复杂,部分代码解读如下:

protected void autowireByType(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
    //对于java容器类属性,autowiredBeanNames存储元素类型匹配的所有beanNames,
    //对于非java容器类属性,autowiredBeanNames只存了1个元素
	Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
	//找出需要被注入属性值的属性名称
    //不需要注入的情况:属性的写方法是cglib方法&未被超类声明、属性是指定忽略的类型(or接口实现)、
    //属性的值已经在beanDefinition中指定、属性是简单类型、属性是arry但元素是简单类型
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) {
		try {
			//获取属性的描述,会递归解析嵌套属性
			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
			//不会尝试对Object类型自动装配,即使它是unsatisfied & 非简单属性
			if (Object.class != pd.getPropertyType()) {
				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
				//是否可以立即处理:实现了PriorityOrdered接口不可以立即处理
				boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
				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.isTraceEnabled()) {
						logger.trace("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);
		}
	}
}



public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
		@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

	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;
	}
}



public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    //设置当前依赖注入点,返回前一个依赖注入点,finally语句又恢复设置.?不确定如此设计的原因?
	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
		Object shortcut = descriptor.resolveShortcut(this);
		if (shortcut != null) {
			return shortcut;
		}

		Class<?> type = descriptor.getDependencyType();
        // 支持注解@value?xml文件配置返回null
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			if (value instanceof String) {
				String strVal = resolveEmbeddedValue((String) value);
				BeanDefinition bd = (beanName != null && containsBean(beanName) ?
						getMergedBeanDefinition(beanName) : null);
				value = evaluateBeanDefinitionString(strVal, bd);
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			try {
				return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
			}
			catch (UnsupportedOperationException ex) {
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}
		}
        // 对集合、map、数组、stream等java容器类型解析
		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}
        //1.按类型匹配找出所有的「候选beanName」
        //   1.1 遍历beanFactory中的List<String> beanDefinitionNames:
        //       1.1.1 根据是否实例化、beanDefinition判断类型是否匹配,存入List<String>
        //2.遍历「候选beanName」,跳过autowire-candidate="false"的beanName
        //   2.1 如果候选bean未实例化,按键=候选beanName、值=候选bean类型
        //       如果已实例化,按键=beanName、值=bean实例,存入Map<String, Object>
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		String autowiredBeanName;
		Object instanceCandidate;

		if (matchingBeans.size() > 1) {
            // 决定策略:是否primary、最高优先级、兜底(遍历返回第一个满足的)
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			if (autowiredBeanName == null) {
				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
					return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
				}
				else {
					return null;
				}
			}
			instanceCandidate = matchingBeans.get(autowiredBeanName);
		}
		else {
			// 只有1个
			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) {
            //调用beanFactory的getBean(...)方法
			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);
	}
}

参考资料

《spring技术内幕》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值