栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Spring-IOC】依赖注入

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring-IOC】依赖注入

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
属性注入注解方式和xml配置方式,使用不同的逻辑。
注解通过从beanFactory中找实例,反射注入;xml则是通过PropertyValues,反射调用set方法注入。

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

		。。。。。

		// bean处理器的方法,实例化后处理方法
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
		
		// 这里得到的是xml配置中设置的属性-值
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		// 如果设置为自动注入。
		// AUTOWIRE_BY_NAME会根据属性的名称,从beanFactory中找bean,添加到newPvs属性集合中
		// AUTOWIRE_BY_TYPE根据属性的类型找bean,添加到属性集合中
		// 当然如果已经在xml中设置值的就不会在找了
		// xml是手动设置,这里是自动配置,直接根据属性的名称或者类型找bean.
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

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

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			// 这里是注解注入的处理逻辑,使用bean处理器的方法。
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
		// 这里设值是属性集合中的属性键值对。
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

xml配置的bean,会将属性和值封装在PropertyValue中,添加到属性集合中,通过反射调用set方法注入。逻辑在applyPropertyValues方法中;

注解的注入则是使用bean处理器,通过反射直接对属性赋值。

直接分析注解的方式,先来看看注解的使用:

@Autowired注解:可以标注在属性上,方法上。

    标注在属性上,会根据属性的类型找bean。标注在方法上,会根据方法参数的类型找bean.如果有多个类型一致的;会跑异常,解决方式设置@primary bean,设置一个候选的。或者在类型一致的里面根据名称选出一个bean,使用@Qualifier注解;

@Resource注解:可以标注在属性上,方法上,但是这个方法的参数个数必须是1个。

    标注在属性上,默认是@Resource的value值作为找bean的名称;如果没有,使用属性的名称;如果不存在该名称的bean,会根据bean的类型找;如果标注在方法上,如果这个方法的名称不是JavaBean规范,那么会根据方法名成找bean,没有找到会根据方法参数的类型找。如果是javaBean规范,那么找bean的名称就是属性名称,根据名称找,根据bean名称没有找到,会根据参数类型找。
CommonAnnotationBeanPostProcessor

使用@Resource注入,需要明确是@Resource不是Spring的注解,是JSR标准

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties直接看这个注入的方法了,其实在依赖输入之前,postProcessMergedBeanDefinition这个方法会进行依赖注入的解析,保存缓存中,在postProcessProperties是从缓存找取,执行注入逻辑。所以直接看postProcessProperties方法也无妨。

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		// 缓存了需要输入数据的信息
		Injectionmetadata metadata = findResourcemetadata(beanName, bean.getClass(), pvs);
		try {
			// 注入逻辑。
			metadata.inject(bean, beanName, pvs);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
		}
		return pvs;
	}

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#buildResourcemetadata
解析需要注入的信息

	private Injectionmetadata buildResourcemetadata(final Class clazz) {
		if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
			return Injectionmetadata.EMPTY;
		}

		List elements = new ArrayList<>();
		Class targetClass = clazz;

		do {
			final List currElements = new ArrayList<>();
			// 得到所有的属性信息
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				// 兼容其他注解
				。。。。。。
				// 我们只关注Resource注解的。
				else if (field.isAnnotationPresent(Resource.class)) {
					// 静态的属性不能注入
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@Resource annotation is not supported on static fields");
					}
					// 将属性封装为ResourceElement
					if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
						currElements.add(new ResourceElement(field, field, null));
					}
				}
			});

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
				if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {				
					// 兼容其他注解
					。。。。。

					// 只看Resource注解
					else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
						// 静态的方法不能注入
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@Resource annotation is not supported on static methods");
						}
						// 方法参数个数不是1的会抛异常。
						Class[] paramTypes = method.getParameterTypes();
						if (paramTypes.length != 1) {
							throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
						}
						// 封装为ResourceElement
						if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
							PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
							currElements.add(new ResourceElement(method, bridgedMethod, pd));
						}
					}
				}
			});

			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		// 循环,从父类中是否有标注注解的。
		while (targetClass != null && targetClass != Object.class);

		return Injectionmetadata.forElements(elements, clazz);
	}

解析注解:

    静态属性和静态方法不能出入;方法的参数个数必须是1个,否则会跑异常。将数据给封装在ResourceElement再添加到集合中。

注入逻辑:

	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		Collection checkedElements = this.checkedElements;
		Collection elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			// 遍历InjectedElement集合,调用InjectedElement 的注入方法。
			for (InjectedElement element : elementsToIterate) {
				if (logger.isTraceEnabled()) {
					logger.trace("Processing injected element of bean '" + beanName + "': " + element);
				}
				element.inject(target, beanName, pvs);
			}
		}
	}
		protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
				throws Throwable {
			// 属性,通过反射
			if (this.isField) {
				Field field = (Field) this.member;
				ReflectionUtils.makeAccessible(field);
				field.set(target, getResourceToInject(target, requestingBeanName));
			}
			else {
				if (checkPropertySkipping(pvs)) {
					return;
				}
				try {
					// 方法,方法的反射。
					Method method = (Method) this.member;
					ReflectionUtils.makeAccessible(method);
					method.invoke(target, getResourceToInject(target, requestingBeanName));
				}
				catch (InvocationTargetException ex) {
					throw ex.getTargetException();
				}
			}
		}

getResourceToInject通过该方法得到值;
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject

		protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
			//这里有一个懒加载的操作。
			// 如果使用@lazy注解标注了,会给创建一个代理,只有再使用的时候才会取bean工厂中找bean
			//非懒加载的会立刻执行找bean的逻辑,返回结果。懒加载是先返回要给代理,等调用放的时候再去执行找bean的过程。
			return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
					getResource(this, requestingBeanName));
		}
	protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
			throws NoSuchBeanDefinitionException {

		Object resource;
		Set autowiredBeanNames;
		// 如果是属性,这里是注解value的值,没有指定,就是属性的名称
		// 如果是方法,javabean标准,是属性名称;不是javaBean标准,则是方法名称。
		String name = element.name;

		if (factory instanceof AutowireCapableBeanFactory) {
			AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
			DependencyDescriptor descriptor = element.getDependencyDescriptor();
			// 如果按照名称找,但是名称没有,就按类型找。
			if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
				autowiredBeanNames = new linkedHashSet<>();
				resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
				if (resource == null) {
					throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
				}
			}
			// 按照名称找。
			else {
				resource = beanFactory.resolveBeanByName(name, descriptor);
				autowiredBeanNames = Collections.singleton(name);
			}
		}
		else {
			resource = factory.getBean(name, element.lookupType);
			autowiredBeanNames = Collections.singleton(name);
		}

		if (factory instanceof ConfigurableBeanFactory) {
			ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
			for (String autowiredBeanName : autowiredBeanNames) {
				if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
					beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
				}
			}
		}

		return resource;
	}

按照名称找不到,就会按照类型找。

		public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
			super(member, pd);
			Resource resource = ae.getAnnotation(Resource.class);
			// Resource 指定的bean名称
			String resourceName = resource.name();
			Class resourceType = resource.type();
			this.isDefaultName = !StringUtils.hasLength(resourceName);
			// 如果使用默认的名称
			if (this.isDefaultName) {
				// 属性名称或者方法名称
				resourceName = this.member.getName();
				// 如果是方法,兵器是set开头,长度>3,是javaBean规范
				// 内省机制找到属性名。否则还是方法名称。
				if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
					resourceName = Introspector.decapitalize(resourceName.substring(3));
				}
			}
			else if (embeddedValueResolver != null) {
				resourceName = embeddedValueResolver.resolveStringValue(resourceName);
			}
			if (Object.class != resourceType) {
				checkResourceType(resourceType);
			}
			else {
				// No resource type specified... check field/method.
				resourceType = getResourceType();
			}
			this.name = (resourceName != null ? resourceName : "");
			this.lookupType = resourceType;
			String lookupValue = resource.lookup();
			this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
			Lazy lazy = ae.getAnnotation(Lazy.class);
			this.lazyLookup = (lazy != null && lazy.value());
		}
AutowiredAnnotationBeanPostProcessor

使用@Autowired注解注入。该注解是Spring的注解。

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#buildResourcemetadata

	private Injectionmetadata buildAutowiringmetadata(final Class clazz) {
		if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
			return Injectionmetadata.EMPTY;
		}

		List elements = new ArrayList<>();
		Class targetClass = clazz;

		do {
			final List currElements = new ArrayList<>();
			// 遍历所有的属性
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				// 属性使用注解标准@Autowired,@Value,@Inject
				// @Inject是JSR标注的注解。
				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;
					}
					// 封装为AutowiredFieldElement
					boolean required = determineRequiredStatus(ann);
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
				MergedAnnotation 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);
						}
					}
					// 封装为AutowiredMethodElement
					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);

		return Injectionmetadata.forElements(elements, clazz);
	}
    静态的都不行属性封装为AutowiredFieldElement;方法封装为AutowiredMethodElement

属性:

		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 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) {
							this.cachedFieldValue = desc;
							registerDependentBeans(beanName, autowiredBeanNames);
							if (autowiredBeanNames.size() == 1) {
								String autowiredBeanName = autowiredBeanNames.iterator().next();
								if (beanFactory.containsBean(autowiredBeanName) &&
										beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
									this.cachedFieldValue = new ShortcutDependencyDescriptor(
											desc, autowiredBeanName, field.getType());
								}
							}
						}
						else {
							this.cachedFieldValue = null;
						}
						this.cached = true;
					}
				}
			}
			// 反射给属性赋值
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}
	}

方法:

		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 {
				int argumentCount = method.getParameterCount();
				arguments = new Object[argumentCount];
				DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
				Set autowiredBeans = new linkedHashSet<>(argumentCount);
				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;
						}
						//找到的bean放再数组中
						arguments[i] = arg;
					}
					catch (BeansException ex) {
						throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
					}
				}
				synchronized (this) {
					if (!this.cached) {
						if (arguments != null) {
							DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
							registerDependentBeans(beanName, autowiredBeans);
							if (autowiredBeans.size() == argumentCount) {
								Iterator it = autowiredBeans.iterator();
								Class[] paramTypes = method.getParameterTypes();
								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();
				}
			}
		}

有个问题;静态的属性和方法都还不能用注解,那如果就是想用静态的怎么版呢?

解决静态属性,静态方法注入的问题

可以这样

@Component
public class UserHelper {

    static UCClient ucClient;

    @Autowired
    public void setUcClient(UCClient ucClient) {
        UserHelper.ucClient = ucClient;
    }
}

但是想想工具类都是静态的,不用交给spring管理。
SmartInitializingSingleton该接口会在所有的bean都实例化之后调用

@Component
public class AutowireStaticSmartInitializingSingleton implements SmartInitializingSingleton {

    @Autowired
    private AutowireCapableBeanFactory beanFactory;

    
    @Override
    public void afterSingletonsInstantiated() {
        // 交给工厂,给我注如,
        beanFactory.autowireBean(new UserHelper());
    }
}

这样该类就不用加@Component注解。工具类交给beanFactory,让工厂注入。

public class UserHelper {

    static UCClient ucClient;
    @Autowired
    public void setUcClient(UCClient ucClient) {
        UserHelper.ucClient = ucClient;
    }
}

或者这样:

@Component
public class AutowireStaticSmartInitializingSingleton implements SmartInitializingSingleton {

    @Autowired
    private AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor;
    // 就是让处理器给注入
    @Override
    public void afterSingletonsInstantiated() {
        autowiredAnnotationBeanPostProcessor.processInjection(new UserHelper());
    }
}

还有一个问题,就是工厂找bean,是如何找的呢?就是方法beanFactory.resolveDependency的逻辑是什么样呢?

beanFactory.resolveDependency方法
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set 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();
			// 解析@value注解的value值
			// @value(#{beanName}) 注入的是bean
			// @value(${property-key}) 属性赋值
			// value 不用的表达式,结果式不同的
			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) {
					// 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()));
				}
			}







			// 如果类型是集合类型的,数组,集合,Map,进入到此
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}



			// 不是集合类型的,就直接找对应的类型。
			Map 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) {
				// 筛选
				// 1. 设置primary
				// 2. Priority注解
				// 3.bean的名称和属性的名称匹配。
				// 如果还欸有筛选出来就抛异常
				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 {
				// We have exactly one match.
				Map.Entry entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			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;
			}
			if (!ClassUtils.isAssignablevalue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}
    处理@value注解类型是集合类型的普通类类型的。如果没有找到,又是必须的,报错如果找到了多个,就筛选1,设置primary的,2.注解Priority的,3.bean名和属性名一致的;如果还灭有筛选出来就报错。
findAutowireCandidates方法

找出对应类型的所有bean

	protected Map findAutowireCandidates(
			@Nullable String beanName, Class requiredType, DependencyDescriptor descriptor) {
		//遍历所有的beanName,从里面找出beanDefinition,找出class,对比clas类型和requiredType
		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
		Map result = new linkedHashMap<>(candidateNames.length);

		// 处理spring内部的实例
		// applicationcontext ,beanFactory等。。
		for (Map.Entry, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
			Class autowiringType = classObjectEntry.getKey();
			if (autowiringType.isAssignableFrom(requiredType)) {
				Object autowiringValue = classObjectEntry.getValue();
				autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
				if (requiredType.isInstance(autowiringValue)) {
					result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
					break;
				}
			}
		}
		// 得到所有类型一样的
		// 进行泛型和@Qualifier的筛选
		for (String candidate : candidateNames) {
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}
		// 如果没有则放宽条件:可以自引用;泛型不在精确匹配
		if (result.isEmpty()) {
			boolean multiple = indicatesMultipleBeans(requiredType);
			// Consider fallback matches if the first pass failed to find anything...
			DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
			// 泛型不在精确匹配 
			for (String candidate : candidateNames) {
				if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
						(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
					addCandidateEntry(result, candidate, descriptor, requiredType);
				}
			}	
			// 可以自引用
			if (result.isEmpty() && !multiple) {
				// Consider self references as a final pass...
				// but in the case of a dependency collection, not the very same bean itself.
				for (String candidate : candidateNames) {
					if (isSelfReference(beanName, candidate) &&
							(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
							isAutowireCandidate(candidate, fallbackDescriptor)) {
						addCandidateEntry(result, candidate, descriptor, requiredType);
					}
				}
			}
		}
		return result;
	}
    找到所有的类型一样的泛型筛选@Qualifier筛选名称。

泛型是精确匹配:
注入的是RedisTemplate;但是容器中只有RedisTemplate由于精确匹配,不能注入

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/732919.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号