spring源码阅读1: @Autowired字段注入

spring源码阅读1: @Autowired字段注入


spring 提供了四种依赖注入的方式:

  • setter注入
  • 构造器注入
  • 字段注入
  • 方法注入

在项目中,我们使用的最多的就是基于@Autowired的字段注入,下面我们基于非延时加载的单例的spring bean结合源码分析以下spring 是如何实现基于@Autowired的字段注入的。

源码阅读

@Autowire 的处理流程包含在spring bean的创建流程中,因此我们的源码阅读从AbstractAutowireCapableBeanFactory.doCreateBean()开始。

源码一:AbstractAutowireCapableBeanFactory.doCreateBean()
该方法是spring 根据 beanDefinition 创建spring bean的核心代码,该方法返回的就是spring bean对象

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
		    // 返回spring bean实例,如果没有指定构造器或者工厂方法,通常就是简单的通过无参构造器返回一个对象。注意这时候返回的对象,所有的字段都还是默认值
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		
		// 省略部分代码
		
	    // spring 用于解决循环依赖的缓存,不在本篇文章的讨论范围,下篇文章再讨论
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
		    // 会在这一步调用AutowiredAnnotationBeanPostProcessor的postProcessProperties方法,处理@Autowire、@value等注入,详情见源码2
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
       // 省略部分代码 
		return exposedObject;
	}

源码二:AutowiredAnnotationBeanPostProcessor.postProcessProperties()

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	    // 获取标注了@Autowired、@Value 或者@Inject 主键的字段 封装为InjectionMetadata 
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
		    // 处理@Autowired的注入,详情见源码3
			metadata.inject(bean, beanName, pvs);
		}
		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}

源码三:InjectionMetadata.inject()

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		Collection<InjectedElement> checkedElements = this.checkedElements;
		Collection<InjectedElement> elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
		    // 遍历需要插入字段(注意InjectedElement不仅仅代表字段,也可以代表构造器,方法等),然后调用InjectedElement.inject()方法
			for (InjectedElement element : elementsToIterate) {
				if (logger.isTraceEnabled()) {
					logger.trace("Processing injected element of bean '" + beanName + "': " + element);
				}
				// 调用InjectedElement.inject()方法,  详情见源码4;
				element.inject(target, beanName, pvs);
			}
		}
	}

源码四:AutowiredFieldElement.inject()

	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 {
				    // 根据类型在ioc容器中查找对应的spring bean。如果依赖的的spring bean 还没有创建,就会先初始化对应的bean。 
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
			// 省略部分代码   
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				// 将对应的spring bean 设置到字段中
				field.set(bean, value);
			}
		}

注1:注意这里的InjectedElement 是 AutowiredAnnotationBeanPostProcessor 内部的InjectedElement 而不是InjectionMetadata的内部的InjectedElement 。

总结

限于篇幅,本文只是简单的阐述了@Autowired在源码中的主要流程,忽略了源码中很多细节,例如:源码4中DefaultListableBeanFactory.resolveDependency()中是如何处理单个对象的注入,集合对象的注入等等。这些都还需要翻看源码,细细阅读。事实上上述流程同样适用于@Value 注解的注入,只是在DefaultListableBeanFactory.resolveDependency() 中有些区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值