Spring源码之依赖注入

在这篇博客中,我们将深入探讨Spring容器启动过程中,单例Bean实例化后的依赖注入,如下流程图:

在这里插入图片描述

调用链路

首先根据前面的知识,我们知道Spring Bean的依赖注入是在Bean实例化后,根据下列调用链路,我们找到具体逻辑执行的地方.

// 首次进入refresh()
refresh();
// -> 实例化非懒加载的单例Bean
finishBeanFactoryInitialization(beanFactory);
// ->
beanFactory.preInstantiateSingletons();
// -> 我们来看简单的单例Bean
getBean(beanName);
// -> doGetBean(..) 
if (mbd.isSingleton()) {
	sharedInstance = getSingleton(beanName, () -> {
		try {
			// 创建Bean 
			return createBean(beanName, mbd, args);
			}
		catch (BeansException ex) {
			destroySingleton(beanName);
			throw ex;
			}
		});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// -> createBean(..) 
// 只展示关键代码
...
try {
// 实例化
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	if (logger.isTraceEnabled()) {
	ogger.trace("Finished creating instance of bean '" + beanName + "'");
	}
	return beanInstance;
}
...

查看具体的doCreateBean(beanName, mbdToUse, args)方法

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
 
    if (instanceWrapper == null) {
    	// 实例化Bean
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
   ...
    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;
        }
    }
   ...
    Object exposedObject = bean;
    try {
        // 填充Bean的属性
        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);
        }
    }
...
// 上述代码我们简单只看3个部分
// 1.Bean实例化 -> 依赖注入是在Bean实例化结束后
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 2.执行后置处理器
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
// 3.填充属性(依赖注入)
populateBean(beanName, mbd, instanceWrapper);

下面我们主要来分析上述2,3两点

寻找切入点

Spring在依赖注入前,会调用Bean的后置处理器,把所有注入点提前找到缓存起来.这里使用到的后置处理器就是AutowiredAnnotationBeanPostProcessor,
类似的这个AutowiredAnnotationBeanPostProcessor也是在this.reader = new AnnotatedBeanDefinitionReader(this);构造方法里提前注册的.

// 找寻注入点
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
// -> 
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
			processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}
// ->找到AutowiredAnnotationBeanPostProcessor的实现
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

可以看到最终返回一个InjectionMetadata对象,现在让我们看这里最关键的逻辑方法
metadata = buildAutowiringMetadata(clazz);

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
    // 如果类不是候选类(没有相关的@Autowired注解),则返回空的InjectionMetadata
    if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
        return InjectionMetadata.EMPTY;
    }

    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        // 处理类中的字段
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            // 查找字段上的@Autowired注解
            MergedAnnotation<?> ann = findAutowiredAnnotation(field);
            if (ann != null) {
                // 检查字段是否为静态字段
                if (Modifier.isStatic(field.getModifiers())) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation is not supported on static fields: " + field);
                    }
                    return;
                }
                // 确定注入是否是必需的
                boolean required = determineRequiredStatus(ann);
                currElements.add(new AutowiredFieldElement(field, required));
            }
        });

        // 处理类中的方法
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            // 查找方法上的@Autowired注解
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            // 检查方法和桥接方法之间的可见性关系
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            // 查找方法上的@Autowired注解
            MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                // 检查方法是否为静态方法-> 排除静态修饰的(static是类级别的)
                if (Modifier.isStatic(method.getModifiers())) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation is not supported on static methods: " + method);
                    }
                    return;
                }
                // 检查方法是否有参数
                if (method.getParameterCount() == 0) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation should only be used on methods with parameters: " +
                                method);
                    }
                }
                // 确定注入是否是必需的
                boolean required = determineRequiredStatus(ann);
                // 查找方法对应的属性描述符
                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                currElements.add(new AutowiredMethodElement(method, required, pd));
            }
        });

        elements.addAll(0, currElements);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    // 根据收集到的注入元素创建InjectionMetadata实例
    return InjectionMetadata.forElements(elements, clazz);
}

// @Autowired、@Value修饰的都可以作为切入点
	public AutowiredAnnotationBeanPostProcessor() {
		this.autowiredAnnotationTypes.add(Autowired.class);
		this.autowiredAnnotationTypes.add(Value.class);
		try {
			this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
					ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
			logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

总结上述代码:分别遍历类的字段和方法将类中所有的注入点找到,封装成InjectionMetadata对象返回.
然后将这些对象全部放入缓存中injectionMetadataCache(在后续依赖注入的时候再使用).

依赖注入

现在我们进入populateBean(beanName, mbd, instanceWrapper);方法,即属性填充.

// 直接来到关键代码,这里也是通过后置处理器去依赖注入
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;
			}

// getBeanPostProcessorCache()方法中获取AutowiredAnnotationBeanPostProcessor,
// 因为AutowiredAnnotationBeanPostProcessor实现了InstantiationAwareBeanPostProcessor
BeanPostProcessorCache getBeanPostProcessorCache() {
		BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
		if (bpCache == null) {
			bpCache = new BeanPostProcessorCache();
			for (BeanPostProcessor bp : this.beanPostProcessors) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					// 获取AutowiredAnnotationBeanPostProcessor
					bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
					if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
						bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
					}
				}
				if (bp instanceof DestructionAwareBeanPostProcessor) {
					bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
				}
				if (bp instanceof MergedBeanDefinitionPostProcessor) {
					bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
				}
			}
			this.beanPostProcessorCache = bpCache;
		}
		return bpCache;
	}

现在来看bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);我们进入AutowiredAnnotationBeanPostProcessor

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 寻找bean的自动装配元数据-> 这里直接从缓存获取,前面找寻注入点已经找过了
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        // 调用自动装配元数据的inject方法,将属性值注入到bean中
        metadata.inject(bean, beanName, pvs);
    } catch (BeanCreationException ex) {
        throw ex;
    } catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    // 返回经过处理的PropertyValues对象
    return pvs;
}

现在我们进入 metadata.inject(bean, beanName, pvs);

// 拿出所有注入点
Collection<InjectedElement> checkedElements = this.checkedElements;
// 循环遍历
for (InjectedElement element : elementsToIterate) {
	element.inject(target, beanName, pvs);
}

进入element.inject(target, beanName, pvs);我们以@Autowired的字段Fifield实现为例

// 这段代码的主要功能是将解析到的属性值通过反射设置到对象的字段中
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // 获取字段对象
    Field field = (Field) this.member;
    Object value;
    if (this.cached) {
        // 如果缓存字段值,直接获取缓存的值
        value = resolvedCachedArgument(beanName, this.cachedFieldValue);
    } else {
        // 如果没有缓存字段值
        DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
        desc.setContainingClass(bean.getClass());
        Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
        Assert.state(beanFactory != null, "No BeanFactory available");
        TypeConverter typeConverter = beanFactory.getTypeConverter();
        try {
            // 解析依赖,并获取对应的值
            value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
        } catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
        }
        synchronized (this) {
            if (!this.cached) {
                if (value != null || this.required) {
                    // 如果有值或者是必需的依赖,缓存依赖描述符,并注册相关的依赖bean
                    this.cachedFieldValue = desc;
                    registerDependentBeans(beanName, autowiredBeanNames);
                    if (autowiredBeanNames.size() == 1) {
                        String autowiredBeanName = autowiredBeanNames.iterator().next();
                        if (beanFactory.containsBean(autowiredBeanName) &&
                                beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                            // 如果只有一个自动注入的依赖bean,且类型匹配,缓存快捷依赖描述符
                            this.cachedFieldValue = new ShortcutDependencyDescriptor(
                                    desc, autowiredBeanName, field.getType());
                        }
                    }
                } else {
                    // 如果没有值且非必需的依赖,将缓存字段值置为null
                    this.cachedFieldValue = null;
                }
                this.cached = true;
            }
        }
    }
    if (value != null) {
        // 如果有值,使用反射将值设置到字段中
        ReflectionUtils.makeAccessible(field);
        field.set(bean, value);
    }
}

我们来看关键的方法beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

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()) {
        // 如果是Optional类型的依赖,创建Optional类型的依赖对象
        return createOptionalDependency(descriptor, requestingBeanName);
    } else if (ObjectFactory.class == descriptor.getDependencyType() ||
            ObjectProvider.class == descriptor.getDependencyType()) {
        // 如果是ObjectFactory或ObjectProvider类型的依赖,创建相应的依赖对象
        return new DependencyObjectProvider(descriptor, requestingBeanName);
    } else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
        // 如果是javax.inject.Provider类型的依赖,使用Jsr330Factory创建依赖提供者对象
        return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
    } else {
        // 对于其他类型的依赖(这里是懒加载@Lazy)
        Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                descriptor, requestingBeanName);
        if (result == null) {
            // 如果没有懒解析的代理对象,则通过doResolveDependency方法解析依赖并返回结果
            result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
        }
        return result;
    }
}

继续查看方法doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    // 设置当前的注入点,用于构造器注入时的循环依赖检查
    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    try {
        // 解析依赖的快捷方式,如果有则返回对应的依赖对象
        Object shortcut = descriptor.resolveShortcut(this);
        if (shortcut != null) {
            return shortcut;
        }

        // 获取依赖的类型
        Class<?> type = descriptor.getDependencyType();
        // 获取自动装配候选解析器返回的建议值
        Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
        if (value != null) {
            if (value instanceof String) {
                // 如果建议值是字符串类型,解析字符串中的占位符并根据BeanDefinition进行解析
                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) {
                // 如果转换器不支持TypeDescriptor解析,则根据字段或方法参数进行转换
                return (descriptor.getField() != null ?
                        converter.convertIfNecessary(value, type, descriptor.getField()) :
                        converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
            }
        }

        // 解析多个候选依赖对象
        Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
        if (multipleBeans != null) {
            return multipleBeans;
        }

        // 查找符合自动装配条件的候选依赖对象
        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) {
            // 存在多个符合条件的候选依赖对象,确定使用哪个候选依赖对象
            autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
            if (autowiredBeanName == null) {
                if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                    // 如果是必需的依赖或者不支持多个依赖,则抛出不唯一的依赖异常
                    return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                } else {
                    // 对于可选的Collection/Map类型的依赖,如果没有唯一的候选依赖对象,则返回null
                    return null;
                }
            }
            instanceCandidate = matchingBeans.get(autowiredBeanName);
        } else {
            // 只有一个符合条件的候选依赖对象
            Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
            autowiredBeanName = entry.getKey();
            instanceCandidate = entry.getValue();
        }

        if (autowiredBeanNames != null) {
            // 将候选依赖对象的名称添加到autowiredBeanNames集合中
            autowiredBeanNames.add(autowiredBeanName);
        }
        if (instanceCandidate instanceof Class) {
            // 如果候选依赖对象是Class类型,通过resolveCandidate方法解析该类型的依赖对象
            instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
        }
        Object result = instanceCandidate;
        if (result instanceof NullBean) {
            // 如果候选依赖对象是NullBean类型,如果是必需的依赖,则抛出异常,否则返回null
            if (isRequired(descriptor)) {
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            result = null;
        }
        if (!ClassUtils.isAssignableValue(type, result)) {
            // 如果候选依赖对象无法分配给依赖类型,则抛出BeanNotOfRequiredTypeException异常
            throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
        }
        return result;
    } finally {
        // 恢复之前的注入点
        ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    }
}

这里情况非常复杂,可以结合最开始的图查看判断逻辑.

// 回看之前的代码,最终通过反射给属性设置值
if (value != null) {
	// 如果有值,使用反射将值设置到字段中
	ReflectionUtils.makeAccessible(field);
	field.set(bean, value);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring中,依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IoC)是相关且密切关联的概念。依赖注入是指将一个对象的依赖关系从代码中移除,而由容器负责创建和注入这些依赖对象。控制反转则是指将对象的创建和生命周期的管理交给容器来处理,而不是由代码直接控制。 在Spring中,IoC容器(例如ApplicationContext)负责实例化、配置和连接bean。当我们使用依赖注入时,我们只需要在需要注入的地方声明相应的依赖,而无需自己负责创建或查找依赖的实例。IoC容器会负责根据配置文件或注解信息,自动将依赖注入到相应的位置。这样可以实现松散耦合,提高代码的可测试性和可维护性。 Spring依赖注入和控制反转的好处在于它们解耦了类之间的依赖关系,提高了代码的灵活性和可扩展性。我们可以通过配置文件或注解来管理对象之间的依赖关系,而不需要修改源代码。这样,我们可以更方便地进行组件替换、模块重用和单元测试。 总结起来,Spring中的依赖注入和控制反转是一种设计模式,它们通过将对象的依赖关系交给容器来管理,提高了代码的可测试性、可扩展性和可维护性。通过使用IoC容器,我们可以简化对象的创建和配置过程,实现松散耦合,提升了应用程序的灵活性。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值