spring 中@Autowired源码解析

使用过@Autowired的都应该知道,这个注解是手动注入依赖对象的,并且先通过bean类型去查找然后再根据属性名去查找

准备4个类:

1 Dao  接口

2 IndexDao 测试类

3 IndexDao2 实现了Dao接口

4 IndexDao3类 实现了Dao接口

public class IndexDao {

  @Autowire

  Dao dao;

}

这样spring启动时肯定会报错:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.luban.dao.Dao' available: expected single matching bean but found 2: indexDao2,indexDao3
 

为什么会出现这个问题呢? 因为Dao有两个实现类,但是在IndexDao中注入时并没有指定使用哪个类,于是先根据类型去查找,查找到了两个,但是这样肯定是不行的,于是查找beanName 为dao的bean,但是还是没有找到,于是就出这个错了,那么怎么证明这个问题呢?下面我们就看看源码来揭开面纱

贴上spring 容器启动源码 :

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
    //只贴出部分代码,
    //刷新容器: 也就是spring 容器初始化,将bean实例化
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			准备工作包括设置启动时间,是否激活标识位,
			// 初始化属性源(property source)配置
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			//返回一个factory 为什么需要返回一个工厂
			//1 因为要对工厂进行初始化
			//zjh
			//返回的是注册bean时的 DefaultListableBeanFactory ,在register中已经将bean(App.class)放入了factory中
			//这个工厂已经有一些值,在new AnnotationConfigApplicationContext()时已经创建
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//准备工厂  配置其标准的特征(通俗来讲是就为beanFactory填充数据)
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.

				//这个方法在当前版本的spring是没用任何代码的
				//可能spring期待在后面的版本中去扩展吧
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//在spring的环境中去执行已经被注册的 factory processors(在获取bd读取器时注册的)
				//设置执行自定义的(通过用户手动add的)BeanFactoryPostProcessors 和spring内部自己定义的(ConfigurationClassPostProcessor)
				//通过CompentScan获取到所有用户自定定义的bean并且存入到map中
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//注册beanPostProcessor  和上一步执行的是不同的bean,这个注册的是可以修改对象中属性的后置处理器
				//注册到DefaultListableBeanFactory(它的父类)中存放后置处理器中的list中
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				//初始化应用事件广播器
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
                
				//开始实例化bean:  这个地方就是我们要讲的地方
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}





}

 2  finishBeanFactoryInitialization(beanFactory); 这个方法就是我们开始讲的地方:   初始化bean

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	      ......................
            ..................

		// Instantiate all remaining (non-lazy-init) singletons.
		//实例化所有的单例对象
		/*  此处是重点*/
		beanFactory.preInstantiateSingletons();
	}

3  调用getBean(String bean)方法获取bean实例

4 经过一系列方法到达了AbstractAutowireCapableBeanFactory.doCreateBean()方法

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

        省略代码

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//设置属性,非常重要 @Autowired和@Resource 也是在这里面注入属性
			//这个地方会调用两次后置处理器的方法  第五次和第六次
			//分别是InstantiationAwareBeanPostProcessor这个类中的 这两个 
            //postProcessAfterInstantiation()和postProcessPropertyValues
			populateBean(beanName, mbd, instanceWrapper);
			//执行后置处理器,aop 就是在这里完成的处理
			//第七次和第八次在这里面完成 执行的是 BeanPostProcessor中的
			//1 postProcessBeforeInitialization
			//2 postProcessAfterInitialization
			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);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

5 通过populateBean(beanName, mbd, instanceWrapper);来填充@Autowired和@Resouece注入的对象

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		boolean continueWithPropertyPopulation = true;

		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//第五次调用后置处理器的方法
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		if (!continueWithPropertyPopulation) {
			return;
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		//自动装配模式: byType好byName
		if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					//这里会解析通过@Autowired和@Resource来注入属性
					//通过AutowireAnnotationBeanPostProcess  解析 @Autowired
					//Comm.......AnnotationBeanPostProcess   解析 @Resource
					//上面两个后置处理器都是spring 注册时放进去的(7个)
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//第六次调用后置处理器方法   填充属性,注入
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}

		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

 

6 上面ibp.postProcessPropertyValues(。。。。)实际上调用的是AutowireAnnotationBeanPostProcess .postProcessPropertyValues()方法,用来专门解析加有@Autowired注解的属性

	@Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			//获取需要注入的值:  这个地方开始-=======
			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;
	}

7 获取当前bean 所有依赖的对象,并且一个一个的注入

	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()) {
			//循环遍历所有需要被依赖的对象
			for (InjectedElement element : elementsToIterate) {
				if (logger.isDebugEnabled()) {
					logger.debug("Processing injected element of bean '" + beanName + "': " + element);
				}
				//注入对象
				element.inject(target, beanName, pvs);
			}
		}
	}

8 AutowiredFieldElement.inject(target,beanBname,pvs),  element包含了被注入属性的信息:类,属性名

@Override
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			
				try {
					//获取需要被注入的对象
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}

		}

9 解析依赖关系

@Override
	@Nullable
	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 Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
             //这是重点
			//一般返回的是空
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				//解析依赖关系: 将被依赖的bean注入: 先根据type然后根据名称
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

10  doResolveDependency();真正去解析依赖的方法

参数1:descriptor 注入对象的类描述信息: 类全名

参数2 :当前bean的名称

参数3 :autowiredBeanNames 传出参数: 注入的bean的搜索符合条件的beanName

参数4:typeConverter: 类型转换器

 

@Nullable
	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) {
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				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;
			}
            //根据注入对象的类型查询匹配到的 bean   可能有多个 比如接口的实现类
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			//根据类型找不到bean, 报错
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;
			//根据bean的类型如果找到了不止一个,那么就根据属性名称来确定注入的bean
			if (matchingBeans.size() > 1) {
                //根据beanName从多个bean匹配
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                //找不到,报错
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(type, matchingBeans);
					}
					else {

						return null;
					}
				}
                //获得bean
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// We have exactly one match.
				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) {
				//如果当前bean依赖的对象并没有创建,那么就会通过下面的方法创建
				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);
		}
	}

根据最后一步分析可知,1 beanType去查询bean,如果存在多个则使用属性名称去匹配,

  如果根据beanType获取不到bean 则直接报错

			//根据类型找不到bean, 报错
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

所有由上面的分析可知,加有@Autowired注解的属性是先通过属性的类型去查找bean,然后再通过属性名去查找

 

又分析不对的地方请指正,谢谢

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坑里水库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值