Spring DI源码分析6--Autowired和Response注解的处理

在上一篇(DI源码分析5)中,在AbstractAutowireCapableBeanFactory#populateBean中会设置bean的属性,其中在InstantiationAwareBeanPostProcessor#postProcessPropertyValues的地方会处理依赖的属性值

CommonAnnotationBeanPostProcessor处理标注了@Resource注解

//CommonAnnotationBeanPostProcessor#postProcessPropertyValues
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		//获取@Resource注解中配置的属性值元数据
		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;
	}

获取@Resource注解中配置的属性值元数据

private InjectionMetadata findResourceMetadata(String beanName, final 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 = buildResourceMetadata(clazz);
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}

构建@Resource的元数据

private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
		LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
		Class<?> targetClass = clazz;

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

			//处理标注注解的属性
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				//javax.xml.ws.WebServiceRef 注解
				if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
					//属性是静态的  抛异常
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
					}
					//加入元素集合
					currElements.add(new WebServiceRefElement(field, field, null));
				}
				//javax.ejb.EJB 注解
				else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@EJB annotation is not supported on static fields");
					}
					currElements.add(new EjbRefElement(field, field, null));
				}
				//Resource 注解
				else if (field.isAnnotationPresent(Resource.class)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("@Resource annotation is not supported on static fields");
					}
					if (!ignoredResourceTypes.contains(field.getType().getName())) {
						currElements.add(new ResourceElement(field, field, null));
					}
				}
			});

			// 处理标注注解的方法   setter方法
			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
				if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
						}
						if (method.getParameterCount() != 1) {
							throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
						}
						PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
						currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
					}
					else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@EJB annotation is not supported on static methods");
						}
						if (method.getParameterCount() != 1) {
							throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
						}
						PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
						currElements.add(new EjbRefElement(method, bridgedMethod, pd));
					}
					else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
						if (Modifier.isStatic(method.getModifiers())) {
							throw new IllegalStateException("@Resource annotation is not supported on static methods");
						}
						Class<?>[] paramTypes = method.getParameterTypes();
						if (paramTypes.length != 1) {
							throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
						}
						if (!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 new InjectionMetadata(clazz, elements);
	}

注入元数据的构造方法

	//org.springframework.beans.factory.annotation.InjectionMetadata#InjectionMetadata
	public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
		this.targetClass = targetClass;
		this.injectedElements = elements;
	}

同上,AutowiredAnnotationBeanPostProcessor处理Autowired注解的属性,方法

	//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

		//获取指定类中autowire相关注解的元信息
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			//对Bean的属性进行自动注入
			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;
	}

获取给定类的autowire相关注解元信息

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
	String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
	//首先从容器中查找是否有给定类的autowire相关注解元信息
	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);
				}
				//解析给定类autowire相关注解元信息
				metadata = buildAutowiringMetadata(clazz);
				//将得到的给定类autowire相关注解元信息存储在容器缓存中
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}

解析给定类autowire相关注解元信息

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
	LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
	Class<?> targetClass = clazz;

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

		//处理属性
		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			//获取属性上的注解
			AnnotationAttributes ann = findAutowiredAnnotation(field);
			if (ann != null) {
				//如果给定属性是静态的,则直接遍历下一个属性
				if (Modifier.isStatic(field.getModifiers())) {
					if (logger.isWarnEnabled()) {
						logger.warn("Autowired annotation is not supported on static fields: " + field);
					}
					return;
				}
				//判断注解的required属性值是否有效
				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;
			}
			AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
			if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
				if (Modifier.isStatic(method.getModifiers())) {
					if (logger.isWarnEnabled()) {
						logger.warn("Autowired annotation is not supported on static methods: " + method);
					}
					return;
				}
				if (method.getParameterCount() == 0) {
					if (logger.isWarnEnabled()) {
						logger.warn("Autowired annotation should only be used on methods with parameters: " +
								method);
					}
				}
				boolean required = determineRequiredStatus(ann);
				//获取当前方法的属性描述符,即方法是可读的(readable)getter方法,还是可写的(writeable)setter方法
				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 new InjectionMetadata(clazz, elements);
}

获取给定对象的autowire相关注解

	private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
		if (ao.getAnnotations().length > 0) {
			//遍历所有相关的注解:@Autowire、@Value、javax.inject.Inject
			for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
				//获取给定对象上的指定类型的注解
				AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
				if (attributes != null) {
					return attributes;
				}
			}
		}
		return null;
	}

获取当前方法的属性描述符,即方法是可读的(readable)getter方法,还是可写的(writeable)setter方法

	public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException {
		Assert.notNull(method, "Method must not be null");
		PropertyDescriptor[] pds = getPropertyDescriptors(clazz);
		for (PropertyDescriptor pd : pds) {
			if (method.equals(pd.getReadMethod()) || method.equals(pd.getWriteMethod())) {
				return pd;
			}
		}
		return null;
	}

调用元数据的注入方法对属性,方法执行注入

	//org.springframework.beans.factory.annotation.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()) {
			boolean debug = logger.isDebugEnabled();
			//这里数个循环,会对属性,方法进行注入
			for (InjectedElement element : elementsToIterate) {
				if (debug) {
					logger.debug("Processing injected element of bean '" + beanName + "': " + element);
				}//注入在下一篇讲
				element.inject(target, beanName, pvs);
			}
		}
	}
对属性注入
	//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.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) {
				//根据Bean名称解析缓存中的属性值
				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 {
					//根据容器中Bean定义,解析指定的依赖关系,获取依赖对象
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
				synchronized (this) {
					//如果当前对象没有被容器缓存
					if (!this.cached) {
						//获取到了当前对象的依赖对象,并且required属性为true
						if (value != null || this.required) {
							this.cachedFieldValue = desc;
							//为指定Bean注册依赖Bean
							registerDependentBeans(beanName, autowiredBeanNames);
							if (autowiredBeanNames.size() == 1) {
								String autowiredBeanName = autowiredBeanNames.iterator().next();
								//如果容器中有指定名称的Bean对象
								if (beanFactory.containsBean(autowiredBeanName)) {
									//依赖对象类型和属性类型匹配,默认按类型注入
									if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
										//创建一个依赖对象的引用,同时缓存
										this.cachedFieldValue = new ShortcutDependencyDescriptor(
												desc, autowiredBeanName, field.getType());
									}
								}
							}
						}
						//如果获取的依赖关系为null,且获取required属性为false
						else {
							//将属性值的缓存设置为null
							this.cachedFieldValue = null;
						}
						//容器已经对当前属性的值缓存
						this.cached = true;
					}
				}
			}
			//如果属性依赖值不为null
			if (value != null) {
				//反射,设置自动的访问控制权限为允许访问
				ReflectionUtils.makeAccessible(field);
				//反射,为Bean对象的属性设置值
				field.set(bean, value);
			}
		}
	}
对方法注入
	//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject
	protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		//如果属性被显式设置为skip,则不进行注入
		if (checkPropertySkipping(pvs)) {
			return;
		}
		//获取注入元素
		Method method = (Method) this.member;
		Object[] arguments;
		//如果有缓存
		if (this.cached) {
			//获取缓存中指定Bean名称的方法参数
			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 {
					//根据容器中Bean定义解析依赖关系,获取方法参数依赖对象
					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];
						for (int i = 0; i < arguments.length; i++) {
							cachedMethodArguments[i] = descriptors[i];
						}
						//为指定Bean注册依赖Bean
						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();
								//容器中存在指定名称的Bean对象
								if (beanFactory.containsBean(autowiredBeanName)) {
									//参数类型和依赖对象类型匹配
									if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
										//创建一个依赖对象的引用,复制给方法相应的参
										cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
												descriptors[i], autowiredBeanName, paramTypes[i]);
									}
								}
							}
						}
						this.cachedMethodArguments = cachedMethodArguments;
					}
					//如果方法参数列表为null,则设置容器对该方法参数的缓存为null
					else {
						this.cachedMethodArguments = null;
					}
					//设置容器已经对该方法缓存
					this.cached = true;
				}
			}
		}
		//方法参数依赖对象不为null
		if (arguments != null) {
			try {
				//反射,显式设置方法的访问控制权限为允许访问
				ReflectionUtils.makeAccessible(method);
				//反射调用Bean的方法
				method.invoke(bean, arguments);
			}
			catch (InvocationTargetException ex){
				throw ex.getTargetException();
			}
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值