SpringBean实例化之@Autowired应用与AutowiredAnnotationBeanPostProcessor解析

前言

Spring的依赖注入(DI):为某个对象的外部资源赋值,注入某个对象所需要的外部资源(包括对象、资源、常量数据等)。
依赖注入:Dependency Injection,简称DI,说白了就是利用反射机制为类的属性赋值的操作。

AutowiredAnnotationBeanPostProcessor是一个bean后置处理器,主要用于对@Autowired和@Value注解解析

一、 @Autowired的实际应用

@Autowired是spring用来进行内部注入的:他注入的值必须存在spring容器中

集合对象注入的查询过程

如果是数组或容器类型的话,Spring可以将所有与目标类型匹配的bean实例都注入进去,不需要判断

public class Father {
@Autowired
private List<Son> stringSon;
@Configuration
public class RootConfig {
    @Bean 
	public List<Son> sonList(){
		return new ArrayList<>();
	}
	@Bean
	public Son son1(){
        return new Son();
	}
	@Bean
	public Son son2(){
          return new Son();
	}
}

容器启动中,spring会将son1和son2加入Father的stringSon集合中。但是son1和son2在stringSon集合的顺序遵循容器中相应目标bean定义的注册顺序,如果我们想使数组或列表中的项目以特定顺序排序,则可以使用@Order或标准@Priority

@Order:默认是最低优先级,值越小优先级越高

@Order(2)
@Bean
public Son son1(){
   //...忽略代码
}

@Order(1)
@Bean
public Son son2(){
     //...忽略代码
}

普通javaBean对象注入的查询过程

1、首先在容器中查询对应类型的bean ,如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
2、如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false
3、如果容器中存在多个同种类型bean,那就装配别名相同的,如果找不到别名相同的在这种情况下@Autowired(required=false)也会报错。

非集合范性对象注入的查询过程

1、首先在容器中查询对应类型和范性的bean ,如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
2、如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false
3、如果容器中存在多个同种类型和范性bean,那就装配别名相同的,如果找不到别名相同的在这种情况下@Autowired(required=false)也会报错。

这种情况的解决方法目前有2种

1、使用 @Qualifier直接点名要哪个

@Qualifier("car1")
@Autowired
private Car car;

2、@Primary 告诉spring容器,如果进行自动装配,那么优先选这个bean

  • 注意:@Primary只能标注到一个同类型的Bean上
@Primary
@Bean
public Car car2(){
       Car car = new Car();
       car.setName("大众");
       return car;
}

标注@Autowired注解的位置对spring对影响

1、标注在构造器上

从Spring Framework4.3开始,@Autowired如果目标bean仅定义一个构造函数作为开始,则不再需要在此类构造函数上添加注释。但是,如果有多个构造函数可用,则必须至少注释一个构造函数,@Autowired以指示容器使用哪个构造函数。

如果我们想spring生产bean的实例时,不要用无参构造器,那么只需在我们想要的执行的构造器上加上@Autowired
其形参是从spring容器中注入,如果spring容器没有其形参值的注入就报错,比如这样

public Father(){
     System.out.println("Father...init")
}
@Autowired
public Father( Son son){
       System.out.println("Father.String name..init");
}

这时我们可以使用@Autowired(required=false),这时如果spring容器没有son,那么spring初始化对象就会使用无参构造器,如果我还想使用有参构造器,这时我们需这样写

@Autowired
public Father(@Nullable  Son son){
       System.out.println("Father.String name..init")
}

spring容器没有son,也会执行这个构造器,注意:@Nullable只有在spring注入时才有这个效果,其他情况下是做提示用的

2、标注在方法上

Spring会先实例化所有Bean,然后根据配置进行扫描,当检测到@Autowired后进行注入,注入时调用这个方法。

3、标注在方法形参上和标准在类的成员属性上

如果放在形参旁边,表示此参数赋值是从IOC容器中寻找(4.3才有),如果此方法上有@Bean注解,则可以省略@Autowired
Spring创建当前类对象,就会调用此方法完成方法参数的赋值,方法参数的赋值是从IOC容器中寻找

二、AutowiredAnnotationBeanPostProcessor类说明

在这里插入图片描述

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    //储存AutowiredAnnotationBeanPostProcessor解析的注解,默认有@Autowired和@Value
	private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);

	private String requiredParameterName = "required";

	private boolean requiredParameterValue = true;

	private int order = Ordered.LOWEST_PRECEDENCE - 2;

	@Nullable
	private ConfigurableListableBeanFactory beanFactory;

	private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));

	private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);
	
    //储存,解析@AutoWired和@Value的属性或方法生成的InjectionMetadata
	private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);


	/**
	 * 默认支持@Autowired和@Value注解
	 * 如果导入了javax.inject.Inject,那么也支持@Inject注解
	 */
	@SuppressWarnings("unchecked")
	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.
		}
	}

从这篇文章SpringBean注册之后置处理器BeanPostProcessor,我们简要说下AutowiredAnnotationBeanPostProcessor各个方法的执行顺序

因为AutowiredAnnotationBeanPostProcessor是一个InstantiationAwareBeanPostProcessor,但其postProcessBeforeInstantiation为null,所以他不行影响spring内部正常的bean实例化流程。在调用bean的构造器后,又因为其是一个MergedBeanDefinitionPostProcessor,所以他会其postProcessMergedBeanDefinition,接着我们来到bean的赋值流程populateBean,其方法postProcessAfterInstantiation返回的是true,所以他会调用其postProcessProperties方法为bean赋值属性,最后其postProcessBeforeInitialization和postProcessAfterInitialization都是直接返回bean的

public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor {

	@Override
	@Nullable
	public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	@Override
	@Nullable
	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	@Override
	public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Override
	@Nullable
	//postProcessBeforeInstantiation为null,所以他不行影响spring内部正常的bean实例化流程
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

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

		return pvs;
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}
三、解析@AutoWired和@Value的属性或方法,把其封装成InjectionMetadata类

该过程发生在doCreateBeanapplyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);片段中。
因为AutowiredAnnotationBeanPostProcessor是一个MergedBeanDefinitionPostProcessor,所以他会执行其postProcessMergedBeanDefinition方法

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,Class<?> beanType, String beanName) {
			InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
			metadata.checkConfigMembers(beanDefinition);
	}
	private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
			// 返回类名作为缓存键,以便与自定义调用方向后兼容。
			String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
			// 首先对并发映射进行快速检查,只需最少的锁定。
			InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
			if (InjectionMetadata.needsRefresh(metadata, clazz)) {
				synchronized (this.injectionMetadataCache) {
					metadata = this.injectionMetadataCache.get(cacheKey);
					if (InjectionMetadata.needsRefresh(metadata, clazz)) {
						if (metadata != null) {
							metadata.clear(pvs);
						}
						metadata = buildAutowiringMetadata(clazz);
						this.injectionMetadataCache.put(cacheKey, metadata);
					}
				}
			}
			return metadata;
	}

	private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
			List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
			Class<?> targetClass = clazz;
	
			do {
				final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
	            
	            //解析属性
				ReflectionUtils.doWithLocalFields(targetClass, field -> {
				    //解析当前对象属性,判断其是否有@Autowired和@value注解,如果有返回其注解对象
					AnnotationAttributes 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);
						//把当前属性封装成AutowiredFieldElement对象储存到injectionMetadataCache中
						currElements.add(new AutowiredFieldElement(field, required));
					}
				});
	            //解析方法
				ReflectionUtils.doWithLocalMethods(targetClass, method -> {
					Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
					if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
						return;
					}
					 //解析当前对象属性,判断其是否有@Autowired和@value注解,如果有返回其注解对象
					AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
					if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					    //如果方法是静态方法,就不处理
						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);
						//把当前方法封装成AutowiredMethodElement对象储存到injectionMetadataCache中
						currElements.add(new AutowiredMethodElement(method, required, pd));
					}
				});
	
				elements.addAll(0, currElements);
	            //开始解析其父类
				targetClass = targetClass.getSuperclass();
			}
			while (targetClass != null && targetClass != Object.class);
			return new InjectionMetadata(clazz, elements);
		}
}

1、解析当前bean的属性,静态属性不解析。把当前属性封装成AutowiredFieldElement对象储存到currElements
2、解析当前bean的方法,静态方法和无参方法不解析。把当前属性封装成AutowiredMethodElement对象储存到currElements
3、把currElements集合封装成一个InjectionMetadata对象储存到injectionMetadataCache中,如下

public class InjectionMetadata {

	private static final Log logger = LogFactory.getLog(InjectionMetadata.class);

	private final Class<?> targetClass;

	private final Collection<InjectedElement> injectedElements;
四、赋值标注@AutoWired和@Value的属性或方法
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
		
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
			//因为前面已经解析过了,所以会在缓存中拿
			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;
	}
}

InjectionMetadata底层的inject方法是遍历其属性injectedElements集合中的InjectedElement的inject方法。从上面的分析我们字段,方法会被封装成AutowiredMethodElement对象。属性封装成AutowiredFieldElement对象。

public class InjectionMetadata {

	private final Class<?> targetClass;
	private final Collection<InjectedElement> injectedElements;
	private volatile Set<InjectedElement> checkedElements;

	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.isTraceEnabled()) {
					logger.trace("Processing injected element of bean '" + beanName + "': " + element);
				}
				element.inject(target, beanName, pvs);
			}
		}
	}

4.1 属性的装配
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {

		@Override
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable{
			// 显然此处父类的member就指的是filed
			Field field = (Field) this.member;
			Object value;
			// 走缓存,关于cachedFieldValue的值
			if (this.cached) {
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			else {
				// 每个Field都包装成一个DependencyDescriptor
				// 如果是Method包装成DependencyDescriptor,毕竟一个方法可以有多个入参
				// 此处包装成它后,显然和元数据都无关了,只和Field有关了  完全隔离
				DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
				desc.setContainingClass(bean.getClass());
				Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
				Assert.state(beanFactory != null, "No BeanFactory available");
				// 转换器使用的bean工厂的转换器~~~
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				try {
					// 获取依赖的value值的工作  最终还是委托给beanFactory.resolveDependency()去完成的~~~~
					//到容器中查询要装配的值,这是自动装配的核心方法。后面出一片文章单独讲解
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
				// 下面代码是把缓存值缓存起来  让同一个Field注入多次能提高效率
				synchronized (this) {
					if (!this.cached) {
						// 可以看到value!=null并且required=true才会进行缓存的处理
						if (value != null || this.required) {
							this.cachedFieldValue = desc;
							// 简单的说就是注册到bean工厂去,比如此处b是依赖a的  所以就注册这个依赖关系进去了
							// 参考this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
							registerDependentBeans(beanName, autowiredBeanNames);
							// autowiredBeanNames里可能会有别名的名称~~~所以size可能大于1
							if (autowiredBeanNames.size() == 1) {
								// beanFactory.isTypeMatch挺重要的~~~~因为@Autowired是按照类型注入的
								String autowiredBeanName = autowiredBeanNames.iterator().next();
								//如果容器中包含这个bean的名字,且类型一样
								if (beanFactory.containsBean(autowiredBeanName) &&beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
									this.cachedFieldValue = new ShortcutDependencyDescriptor(
											desc, autowiredBeanName, field.getType());
								}
							}
						}
						else {
							this.cachedFieldValue = null;
						}
						this.cached = true;
					}
				}
			}
			// 不为null,就完成最终的set值  利用反射给filed属性赋值~~~~
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}
	}
4.2 方法的装配
private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {

		@Override
		protected void inject(Object bean, @Nullable String beanName,@Nullable PropertyValues pvs) throws Throwable {
			if (checkPropertySkipping(pvs)) {
				return;
			}
			Method method = (Method) this.member;
			Object[] arguments;
			if (this.cached) {
				// Shortcut for avoiding synchronization...
				arguments = resolveCachedArguments(beanName);
			}
			else {
				Class<?>[] paramTypes = method.getParameterTypes();
				arguments = new Object[paramTypes.length];
				DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
				Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length);
				Assert.state(beanFactory != null, "No BeanFactory available");
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				for (int i = 0; i < arguments.length; i++) {
					MethodParameter methodParam = new MethodParameter(method, i);
					DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
					currDesc.setContainingClass(bean.getClass());
					descriptors[i] = currDesc;
					try {
					   //到容器中查询要装配的值,这是自动装配的核心方法。后面出一片文章单独讲解
						Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
						if (arg == null && !this.required) {
							arguments = null;
							break;
						}
						arguments[i] = arg;
					}
					catch (BeansException ex) {
						throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
					}
				}
				synchronized (this) {
					if (!this.cached) {
						if (arguments != null) {
							Object[] cachedMethodArguments = new Object[paramTypes.length];
							System.arraycopy(descriptors, 0, cachedMethodArguments, 0, arguments.length);
							registerDependentBeans(beanName, autowiredBeans);
							if (autowiredBeans.size() == paramTypes.length) {
								Iterator<String> it = autowiredBeans.iterator();
								for (int i = 0; i < paramTypes.length; i++) {
									String autowiredBeanName = it.next();
									if (beanFactory.containsBean(autowiredBeanName) &&
											beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
										cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
												descriptors[i], autowiredBeanName, paramTypes[i]);
									}
								}
							}
							this.cachedMethodArguments = cachedMethodArguments;
						}
						else {
							this.cachedMethodArguments = null;
						}
						this.cached = true;
					}
				}
			}
			if (arguments != null) {
				try {
					ReflectionUtils.makeAccessible(method);
					method.invoke(bean, arguments);
				}
				catch (InvocationTargetException ex) {
					throw ex.getTargetException();
				}
			}
		}
五、容器是怎么获取要装配的值
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactoryimplements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

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

		// 把当前Bean工厂的名字发现器赋值给传进来DependencyDescriptor 类
		// 这里面注意了:有必要说说名字发现器这个东西,具体看下面吧==========还是比较重要的
		// Bean工厂的默认值为:private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

		// 支持到Optional类型的注入,比如我们这样注入:private Optional<GenericBean<Object, Object>> objectGenericBean;
		// 也是能够注入进来的,只是类型变为,Optional[GenericBean(t=obj1, w=2)]
		// 对于Java8中Optional类的处理
		if (Optional.class == descriptor.getDependencyType()) {
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		// 兼容ObjectFactory和ObjectProvider(Spring4.3提供的接口)
		// 关于ObjectFactory和ObjectProvider在依赖注入中的大作用,我觉得是非常有必要再撰文讲解的
		//对于前面讲到的提早曝光的ObjectFactory的特殊处理
		else if (ObjectFactory.class == descriptor.getDependencyType() ||
				ObjectProvider.class == descriptor.getDependencyType()) {
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		// 支持到了javax.inject.Provider这个类的实现
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
		}
		// 这个应该是我们觉得部分触及到的,其实不管何种方式,最终都是交给doResolveDependency方法去处理了
		else {
			//getAutowireCandidateResolver()得到ContextAnnotationAutowireCandidateResolver 根据依赖注解信息,找到对应的Bean值信息
			//getLazyResolutionProxyIfNecessary方法,它也是唯一实现。
			//如果字段上带有@Lazy注解,表示进行懒加载 Spring不会立即创建注入属性的实例,而是生成代理对象,来代替实例
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
		
			// 这里如果不是懒加载的(绝大部分情况都走这里) 就进入核心方法doResolveDependency 下面有分解
			if (result == null) {
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}
5.1 获取要装配的值
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
          // 相当于打个点,记录下当前的步骤位置  返回值为当前的InjectionPoint 
		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
		// 简单的说就是去Bean工厂的缓存里去看看,有没有名称为此的Bean,有就直接返回,没必要继续往下走了
			// 比如此处的beanName为:objectGenericBean等等
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			Class<?> type = descriptor.getDependencyType();
			//处理@Value
			//3.1 获取@Value中的值value
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
			     //3.2 解析value
				if (value instanceof String) {
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				//3.3 value转换类型后返回
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
				}
				catch (UnsupportedOperationException ex) {
					// A custom TypeConverter which does not support TypeDescriptor resolution...
					return (descriptor.getField() != null ?
							converter.convertIfNecessary(value, type, descriptor.getField()) :
							converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
				}
			}

			//4. 处理数组和Collections类型
			//因为是数组或容器,Sprng可以直接把符合类型的bean都注入到数组或容器中,处理逻辑是:
			//4.1 确定容器或数组的组件类型
			//4.2 调用findAutowireCandidates方法,获取与组件类型匹配的Map(beanName -> bean实例)
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

		    // 获取所有【类型】匹配的Beans,形成一个Map(此处用Map装,是因为可能不止一个符合条件)
			// 该方法就特别重要了,对泛型类型的匹配、对@Qualifierd的解析都在这里面,下面详情分解
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			
			//6. 结果为空的时候,如果设置的是required,也要抛出异常
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			// 若有多个匹配
			// 需要注意的是:@Qualifier注解在上面就已经生效了~~~~因为AutowireCandidateResolver.isAutowireCandidate是在上面生效的
			if (matchingBeans.size() > 1) {
				// 由它进行判别  从弱水三千中  取出一瓢
				// 1、是否标注有@Primary  有这种bean就直接返回(@Primary只允许标注在一个同类型Bean上)
				// 2、看是否有标注有`javax.annotation.Priority`这个注解的
				// 3、根据字段field名,去和beanName匹配  匹配上了也行(这就是为何我们有时候不用@Qulifier也没事的原因之一)
				// 此处注意:descriptor.getDependencyName()这个属性表示字段名,靠的是`DefaultParameterNameDiscoverer`去把字段名取出来的~
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
					}
					else {
						// In case of an optional Collection/Map, silently ignore a non-unique case:
						// possibly it was meant to be an empty collection of multiple regular beans
						// (before 4.3 in particular when we didn't even look for collection beans).
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// 仅仅只匹配上一个,走这里 很简单  直接拿出来即可
				// 注意这里直接拿出来的技巧:不用遍历,直接用iterator.next()即可
				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}
// 把找到的autowiredBeanName 放进去
			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			// 底层就是调用了beanFactory.getBean(beanName);  确保该实例肯定已经被实例化了的
			if (instanceCandidate instanceof Class) {
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			// 再一次校验,type和result的type类型是否吻合=====
			if (!ClassUtils.isAssignableValue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		// 最终把节点归还回来
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}
5.2 获取要装配的值后,怎么确定要装配那个值
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
		Class<?> requiredType = descriptor.getDependencyType();
		// 看看传入的Bean中有没有标注了@Primary注解的
		String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
		// 如果找到了 就直接返回
		// 由此可见,@Primary的优先级还是非常的高的
		if (primaryCandidate != null) {
			return primaryCandidate;
		}
		//找到一个标注了javax.annotation.Priority注解的。(备注:优先级的值不能有相同的,否则报错)
		String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
		if (priorityCandidate != null) { 
			return priorityCandidate;
		}
		// Fallback
		// 这里是最终的处理(相信绝大部分情况下,都会走这里~~~~~~~~~~~~~~~~~~~~)
		// 此处就能看出resolvableDependencies它的效能了,他会把解析过的依赖们缓存起来,不用再重复解析了
		for (Map.Entry<String, Object> entry : candidates.entrySet()) {
			String candidateName = entry.getKey();
			Object beanInstance = entry.getValue();
			
			// 到这一步就比较简单了,matchesBeanName匹配上Map的key就行。
			// 需要注意的是,bean可能存在很多别名,所以只要有一个别名相同,就认为是能够匹配上的  具体参考AbstractBeanFactory#getAliases方法
			//descriptor.getDependencyName() 这个特别需要注意的是:如果是字段,这里调用的this.field.getName() 直接用的是字段的名称
			// 因此此处我们看到的情况是,我们采用@Autowired虽然匹配到两个类型的Bean了,即使我们没有使用@Qualifier注解,也会根据字段名找到一个合适的(若没找到,就抱错了)
			if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
					matchesBeanName(candidateName, descriptor.getDependencyName())) {
				return candidateName;
			}
		}
		return null;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值