AutowiredAnnotationBeanPostProcessor图解@Autowired @value的原理

AutowiredAnnotationBeanPostProcessor是一个Bean后置处理器,用于处理@Autowired @value的 注入。

1、@Autowired可添加在属性上,通过Spring自动注入属性值

2、@Autowired可添加构造方法,通过Spring容器在创建过程中通过调用BeanPostProcessor的实现子类的determineCandidateConstructors方法,进行构造函数的筛选,确定应该使用的构造函数,对存在多个有参构造函数时,将不指定构造函数使用的范围,交由Spring通过自己的算法进行判断。

3、@Autowired可添加方法上(名字可以随便起,所以并不一定是set方法,普通方法也行),通过Spring自动设置方法参数的值

4、@Value ,通过@value中设置的参数进行注入

5、@Lookup,识别类与父类的添加了@Lookup的抽象方法,并添加到缓存

lookupMethodsChecked中,用作后续的处理

.....

下面是图片,在这里会持续完善

 
  

 

 下面是整个类加了注释的源码

/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.annotation;

import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.support.LookupOverride;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

/**
 * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessor}
 * implementation that autowires annotated fields, setter methods, and arbitrary
 * config methods. Such members to be injected are detected through annotations:
 * by default, Spring's {@link Autowired @Autowired} and {@link Value @Value}
 * annotations.
 *
 * 

Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation, * if available, as a direct alternative to Spring's own {@code @Autowired}. * *

Autowired Constructors

*

Only one constructor of any given bean class may declare this annotation with * the 'required' attribute set to {@code true}, indicating the constructor * to autowire when used as a Spring bean. Furthermore, if the 'required' attribute * is set to {@code true}, only a single constructor may be annotated with * {@code @Autowired}. If multiple non-required constructors declare the * annotation, they will be considered as candidates for autowiring. The constructor * with the greatest number of dependencies that can be satisfied by matching beans * in the Spring container will be chosen. If none of the candidates can be satisfied, * then a primary/default constructor (if present) will be used. If a class only * declares a single constructor to begin with, it will always be used, even if not * annotated. An annotated constructor does not have to be public. * *

Autowired Fields

*

Fields are injected right after construction of a bean, before any * config methods are invoked. Such a config field does not have to be public. * *

Autowired Methods

*

Config methods may have an arbitrary name and any number of arguments; each of * those arguments will be autowired with a matching bean in the Spring container. * Bean property setter methods are effectively just a special case of such a * general config method. Config methods do not have to be public. * *

Annotation Config vs. XML Config

*

A default {@code AutowiredAnnotationBeanPostProcessor} will be registered * by the "context:annotation-config" and "context:component-scan" XML tags. * Remove or turn off the default annotation configuration there if you intend * to specify a custom {@code AutowiredAnnotationBeanPostProcessor} bean definition. * *

NOTE: Annotation injection will be performed before XML injection; * thus the latter configuration will override the former for properties wired through * both approaches. * *

{@literal @}Lookup Methods

*

In addition to regular injection points as discussed above, this post-processor * also handles Spring's {@link Lookup @Lookup} annotation which identifies lookup * methods to be replaced by the container at runtime. This is essentially a type-safe * version of {@code getBean(Class, args)} and {@code getBean(String, args)}. * See {@link Lookup @Lookup's javadoc} for details. * * @author Juergen Hoeller * @author Mark Fisher * @author Stephane Nicoll * @author Sebastien Deleuze * @author Sam Brannen * @since 2.5 * @see #setAutowiredAnnotationType * @see Autowired * @see Value */ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { protected final Log logger = LogFactory.getLog(getClass()); // 该处理器支持解析的注解们,默认支持的是3个 private final Set> autowiredAnnotationTypes = new LinkedHashSet<>(4); // @Autowired(required = false)这个注解的属性值名称 private String requiredParameterName = "required"; // 这个值一般请不要改变(若改成false,效果required = false的作用是相反的了) private boolean requiredParameterValue = true; private int order = Ordered.LOWEST_PRECEDENCE - 2; @Nullable private ConfigurableListableBeanFactory beanFactory; // 对@Lookup方法的支持 private final Set lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256)); // 构造函数候选器缓存 private final Map, Constructor[]> candidateConstructorsCache = new ConcurrentHashMap<>(256); // 方法注入、字段filed注入 // 此处InjectionMetadata这个类非常重要,到了此处@Autowired注解含义已经没有了,完全被准备成这个元数据了 // InjectionMetadata持有targetClass、Collection injectedElements等两个重要属性 // 其中InjectedElement这个抽象类最重要的两个实现为:AutowiredFieldElement和AutowiredMethodElement private final Map injectionMetadataCache = new ConcurrentHashMap<>(256); /** * 构造方法,完成对应注解的注入 * * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's * standard {@link Autowired @Autowired} and {@link Value @Value} annotations. *

Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation, * if available. */ @SuppressWarnings("unchecked") public AutowiredAnnotationBeanPostProcessor() { this.autowiredAnnotationTypes.add(Autowired.class); this.autowiredAnnotationTypes.add(Value.class); try { this.autowiredAnnotationTypes.add((Class) 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. } } /** * 自定义支持的依赖注入注解类型 * * Set the 'autowired' annotation type, to be used on constructors, fields, * setter methods, and arbitrary config methods. *

The default autowired annotation types are the Spring-provided * {@link Autowired @Autowired} and {@link Value @Value} annotations as well * as JSR-330's {@link javax.inject.Inject @Inject} annotation, if available. *

This setter property exists so that developers can provide their own * (non-Spring-specific) annotation type to indicate that a member is supposed * to be autowired. */ public void setAutowiredAnnotationType(Class autowiredAnnotationType) { Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null"); this.autowiredAnnotationTypes.clear(); this.autowiredAnnotationTypes.add(autowiredAnnotationType); } /** * Set the 'autowired' annotation types, to be used on constructors, fields, * setter methods, and arbitrary config methods. *

The default autowired annotation types are the Spring-provided * {@link Autowired @Autowired} and {@link Value @Value} annotations as well * as JSR-330's {@link javax.inject.Inject @Inject} annotation, if available. *

This setter property exists so that developers can provide their own * (non-Spring-specific) annotation types to indicate that a member is supposed * to be autowired. */ public void setAutowiredAnnotationTypes(Set> autowiredAnnotationTypes) { Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty"); this.autowiredAnnotationTypes.clear(); this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes); } /** * Set the name of an attribute of the annotation that specifies whether it is required. * @see #setRequiredParameterValue(boolean) */ public void setRequiredParameterName(String requiredParameterName) { this.requiredParameterName = requiredParameterName; } /** * Set the boolean value that marks a dependency as required. *

For example if using 'required=true' (the default), this value should be * {@code true}; but if using 'optional=false', this value should be {@code false}. * @see #setRequiredParameterName(String) */ public void setRequiredParameterValue(boolean requiredParameterValue) { this.requiredParameterValue = requiredParameterValue; } public void setOrder(int order) { this.order = order; } @Override public int getOrder() { return this.order; } // bean工厂必须是ConfigurableListableBeanFactory的 @Override public void setBeanFactory(BeanFactory beanFactory) { if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { throw new IllegalArgumentException( "AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory); } this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; } /** * 处理合并的bean定义信息 * 1、解析@Autowired等注解然后转换 * 2、把注解信息转换为InjectionMetadata然后缓存到上面的injectionMetadataCache里面 * @param beanDefinition the merged bean definition for the bean * @param beanType the actual type of the managed bean instance * @param beanName the name of the bean */ @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) { // 解析注解并缓存 InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } @Override public void resetBeanDefinition(String beanName) { this.lookupMethodsChecked.remove(beanName); this.injectionMetadataCache.remove(beanName); } /** * 获取构造器集合 * 如果有多个Autowired,required为true,不管有没有默认构造方法,会报异常 * 如果只有一个Autowired,required为false,没有默认构造方法,会报警告 * 如果没有Autowired注解,定义了两个及以上有参数的构造方法,没有无参构造方法, * 其他情况都可以,但是以有Autowired的构造方法优先,然后才是默认构造方法 * * * @param beanClass * @param beanName * @return * @throws BeanCreationException */ @Override @Nullable public Constructor[] determineCandidateConstructors(Class beanClass, final String beanName) throws BeanCreationException { // Let's check for lookup methods here... // 处理包含@Loopup注解的方法,如果集合中没有beanName,则走一遍bean中的所有方法,过滤是否含有lookup方法 if (!this.lookupMethodsChecked.contains(beanName)) { if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) { try { Class targetClass = beanClass; do { // 遍历当前类以及所有父类,找出lookup注解的方法进行处理 ReflectionUtils.doWithLocalMethods(targetClass, method -> { // 获取method上的Lookup注解 Lookup lookup = method.getAnnotation(Lookup.class); // 存在此注解的话,就将方法和注解中的内容构建LookupOverride对象,设置进BeanDefinition中 if (lookup != null) { Assert.state(this.beanFactory != null, "No BeanFactory available"); LookupOverride override = new LookupOverride(method, lookup.value()); try { RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName); mbd.getMethodOverrides().addOverride(override); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition"); } } }); targetClass = targetClass.getSuperclass(); } //遍历父类,直到Object while (targetClass != null && targetClass != Object.class); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Lookup method resolution failed", ex); } } // 无论对象中是否含有@Lookup方法,过滤完成后都会放到集合中,证明此bean已经检查完@Lookup注解 this.lookupMethodsChecked.add(beanName); } // Quick check on the concurrent map first, with minimal locking. // 从缓存中拿构造函数,不存在的话就进入代码块中再拿一遍,还不存在的话就进行下方的逻辑, Constructor[] candidateConstructors = this.candidateConstructorsCache.get(beanClass); // 没找到再同步 if (candidateConstructors == null) { // Fully synchronized resolution now... synchronized (this.candidateConstructorsCache) { //再检测一遍,双重检测 candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { Constructor[] rawCandidates; try { //获取bean中所有的构造函数 rawCandidates = beanClass.getDeclaredConstructors(); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex); } // 暂时候选构造函数集合, List> candidates = new ArrayList<>(rawCandidates.length); // 带有依赖项的构造函数 Constructor requiredConstructor = null; // 默认使用的构造函数 Constructor defaultConstructor = null; // 获取主构造函数 Constructor primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass); // 标识,表示不是合成构造函数的数量 // 合成构造函数->有方法参数并对实例进行赋值的构造函数 int nonSyntheticConstructors = 0; // 遍历所有的构造函数 for (Constructor candidate : rawCandidates) { // 构造函数不是合成构造函数,标识累加 if (!candidate.isSynthetic()) { nonSyntheticConstructors++; } else if (primaryConstructor != null) { continue; } // 查找构造函数上@Autowired注解的属性, MergedAnnotation ann = findAutowiredAnnotation(candidate); // 注解不存在,则再通过方法获取用户类,如果是用户类则返回用户类,还判断了cglib的情况,cglib情况则返回目标类 // 然后获取参数一致的构造函数再获取注解 if (ann == null) { Class userClass = ClassUtils.getUserClass(beanClass); // 如果是有代理的,找到被代理 if (userClass != beanClass) { try { // 获取构造方法 Constructor superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes()); //继续寻找Autowired和value的注解 ann = findAutowiredAnnotation(superCtor); } catch (NoSuchMethodException ex) { // Simply proceed, no equivalent superclass constructor found... } } } // 构造函数上存在注解 if (ann != null) { //有两个Autowired注解,冲突了 if (requiredConstructor != null) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor); } // 获取@Autowired注解中required属性的值 boolean required = determineRequiredStatus(ann); // 为true则将这个构造函数设置为带有依赖项的构造函数并进行判断,不可存在多个带有依赖项的构造函数 if (required) { //如果已经有required=false了,又来了一个required=true的方法就报异常了,这样两个可能就不知道用哪个了 if (!candidates.isEmpty()) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + ". Found constructor with 'required' Autowired annotation: " + candidate); } requiredConstructor = candidate; } // 加入集合 candidates.add(candidate); } // 如果构造函数的参数为零,则是默认构造函数 else if (candidate.getParameterCount() == 0) { defaultConstructor = candidate; } } // 存在@Autowired注解的函数,并且required值为false,则此注解不起作用,但是存在默认构造函数 // 则将默认构造函数添加到集合中,并将集合变为数组使用 if (!candidates.isEmpty()) { // Add default constructor to list of optional constructors, as fallback. if (requiredConstructor == null) { if (defaultConstructor != null) { //添加默认构造函数 candidates.add(defaultConstructor); } else if (candidates.size() == 1 && logger.isInfoEnabled()) { logger.info("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - " + "this constructor is effectively required since there is no " + "default constructor to fall back to: " + candidates.get(0)); } } candidateConstructors = candidates.toArray(new Constructor[0]); } // 如果只存在一个构造函数,且这个构造函数有参数列表,则使用这个构造函数 else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) { //只有一个函数且有参数 candidateConstructors = new Constructor[] {rawCandidates[0]}; } // 如果非合成构造存在两个且有主构造和默认构造,且主构造和默认构造不相等,则这两个一块使用 else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) { //有两个非合成方法,有优先方法和默认方法,且不相同 candidateConstructors = new Constructor[] {primaryConstructor, defaultConstructor}; } // 如果只有一个非合成构造且有主构造,使用主构造 else if (nonSyntheticConstructors == 1 && primaryConstructor != null) { //只有一个优先的 candidateConstructors = new Constructor[] {primaryConstructor}; } // 否则没有能够直接使用的构造 else { //大于2个没注解的构造方法就不知道要用什么了,所以就返回null candidateConstructors = new Constructor[0]; } this.candidateConstructorsCache.put(beanClass, candidateConstructors); } } } // 使用构造列表中没有值,则返回null return (candidateConstructors.length > 0 ? candidateConstructors : null); } /** * 完成bean中@Autowired,@Inject,@Value注解的解析并注入的功能 * @param pvs * @param bean * @param beanName * @return */ @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { // 从缓存中取出这个bean对应的依赖注入的元信息~ 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; } @Deprecated @Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) { return postProcessProperties(pvs, bean, beanName); } /** * 'Native' processing method for direct calls with an arbitrary target instance, * resolving all of its fields and methods which are annotated with one of the * configured 'autowired' annotation types. * @param bean the target instance to process * @throws BeanCreationException if autowiring failed * @see #setAutowiredAnnotationTypes(Set) */ public void processInjection(Object bean) throws BeanCreationException { Class clazz = bean.getClass(); InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null); try { metadata.inject(bean, null, null); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( "Injection of autowired dependencies failed for class [" + clazz + "]", ex); } } /** * 方法名为查找到该bean的依赖注入元信息,内部只要查找到了就会加入到缓存内,下次没必要再重复查找了~ * 它是一个模版方法,真正做事的方法是:buildAutowiringMetadata,它复杂把标注有@Autowired注解的属性转换为Metadata元数据信息,从而消除注解的定义 * 此处查找包括了字段依赖注入和方法依赖注入~~~ * @param beanName * @param clazz * @param pvs * @return */ private InjectionMetadata findAutowiringMetadata(String beanName, Class clazz, @Nullable PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. // 从缓存中获取该类的信息 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; } /** * 去寻找有Autowired和Value注解的属性和方法,也包括自定义的父类的,封装成AutowiredMethodElement放入集合中 * @param clazz * @return */ private InjectionMetadata buildAutowiringMetadata(final Class clazz) { // 如果clazz是JDK中的类,直接忽略,因为不可能标注有这些标注 if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) { return InjectionMetadata.EMPTY; } List elements = new ArrayList<>(); Class targetClass = clazz; do { final List currElements = new ArrayList<>(); // 遍历类中的每个属性,判断属性是否包含指定的属性(通过 findAutowiredAnnotation 方法) // 如果存在则保存,这里注意,属性保存的类型是 AutowiredFieldElement ReflectionUtils.doWithLocalFields(targetClass, field -> { MergedAnnotation ann = findAutowiredAnnotation(field); if (ann != null) { //Autowired注解不支持静态方法 if (Modifier.isStatic(field.getModifiers())) { if (logger.isInfoEnabled()) { logger.info("Autowired annotation is not supported on static fields: " + field); } return; } //查看是否是required的 boolean required = determineRequiredStatus(ann); currElements.add(new AutowiredFieldElement(field, required)); } }); // 遍历类中的每个方法,判断属性是否包含指定的属性(通过 findAutowiredAnnotation 方法) // 如果存在则保存,这里注意,方法保存的类型是 AutowiredMethodElement 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); } } boolean required = determineRequiredStatus(ann); PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); // AutowiredMethodElement里封装了一个PropertyDescriptor(比字段多了一个参数) currElements.add(new AutowiredMethodElement(method, required, pd)); } }); // 父类的都放在第一位,所以父类是最先完成依赖注入的 elements.addAll(0, currElements); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); // InjectionMetadata就是对clazz和elements的一个包装而已 return InjectionMetadata.forElements(elements, clazz); } /** * 只要方法/属性上但凡标注有一个注解,就立马返回了 * @param ao * @return */ @Nullable private MergedAnnotation findAutowiredAnnotation(AccessibleObject ao) { MergedAnnotations annotations = MergedAnnotations.from(ao); for (Class type : this.autowiredAnnotationTypes) { MergedAnnotation annotation = annotations.get(type); if (annotation.isPresent()) { return annotation; } } return null; } /** * Determine if the annotated field or method requires its dependency. *

A 'required' dependency means that autowiring should fail when no beans * are found. Otherwise, the autowiring process will simply bypass the field * or method when no beans are found. * @param ann the Autowired annotation * @return whether the annotation indicates that a dependency is required */ @SuppressWarnings({"deprecation", "cast"}) protected boolean determineRequiredStatus(MergedAnnotation ann) { // The following (AnnotationAttributes) cast is required on JDK 9+. return determineRequiredStatus((AnnotationAttributes) ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType()))); } /** * Determine if the annotated field or method requires its dependency. *

A 'required' dependency means that autowiring should fail when no beans * are found. Otherwise, the autowiring process will simply bypass the field * or method when no beans are found. * @param ann the Autowired annotation * @return whether the annotation indicates that a dependency is required * @deprecated since 5.2, in favor of {@link #determineRequiredStatus(MergedAnnotation)} */ @Deprecated protected boolean determineRequiredStatus(AnnotationAttributes ann) { return (!ann.containsKey(this.requiredParameterName) || this.requiredParameterValue == ann.getBoolean(this.requiredParameterName)); } /** * Obtain all beans of the given type as autowire candidates. * @param type the type of the bean * @return the target beans, or an empty Collection if no bean of this type is found * @throws BeansException if bean retrieval failed */ protected Map findAutowireCandidates(Class type) throws BeansException { if (this.beanFactory == null) { throw new IllegalStateException("No BeanFactory configured - " + "override the getBeanOfType method or specify the 'beanFactory' property"); } return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type); } /** * Register the specified bean as dependent on the autowired beans. */ private void registerDependentBeans(@Nullable String beanName, Set autowiredBeanNames) { if (beanName != null) { for (String autowiredBeanName : autowiredBeanNames) { if (this.beanFactory != null && this.beanFactory.containsBean(autowiredBeanName)) { this.beanFactory.registerDependentBean(autowiredBeanName, beanName); } if (logger.isTraceEnabled()) { logger.trace("Autowiring by type from bean name '" + beanName + "' to bean named '" + autowiredBeanName + "'"); } } } } /** * Resolve the specified cached method argument or field value. */ @Nullable private Object resolvedCachedArgument(@Nullable String beanName, @Nullable Object cachedArgument) { if (cachedArgument instanceof DependencyDescriptor) { DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument; Assert.state(this.beanFactory != null, "No BeanFactory available"); return this.beanFactory.resolveDependency(descriptor, beanName, null, null); } else { return cachedArgument; } } /** * Class representing injection information about an annotated field. */ private class AutowiredFieldElement extends InjectionMetadata.InjectedElement { private final boolean required; private volatile boolean cached = false; @Nullable private volatile Object cachedFieldValue; public AutowiredFieldElement(Field field, boolean required) { super(field, null); this.required = required; } /** * 完成属性的注入 * @param bean * @param beanName * @param pvs * @throws Throwable */ @Override protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field) this.member; Object value; // 如果缓存,从缓存中获取 if (this.cached) { // 如果 cachedFieldValue instanceof DependencyDescriptor。则调用 resolveDependency 方法重新加载。 value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { // 否则调用了 resolveDependency 方法。这个在前篇讲过,在 populateBean 方法中按照类型注入的时候就是通过此方法, // 也就是说明了 @Autowired 和 @Inject默认是 按照类型注入的 DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set autowiredBeanNames = new LinkedHashSet<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); // 转换器使用的bean工厂的转换器 TypeConverter typeConverter = beanFactory.getTypeConverter(); try { // 获取依赖的value值的工作 最终还是委托给beanFactory.resolveDependency()去完成的 // 这个接口方法由AutowireCapableBeanFactory提供,它提供了从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) { // 可以看到value!=null并且required=true才会进行缓存的处理 if (value != null || this.required) { // 这里先缓存一下 desc,如果下面 utowiredBeanNames.size() > 1。则在上面从缓存中获取的时候会重新获取。 this.cachedFieldValue = desc; // 注册依赖bean registerDependentBeans(beanName, autowiredBeanNames); // autowiredBeanNames里可能会有别名的名称,所以size可能大于1 if (autowiredBeanNames.size() == 1) { // beanFactory.isTypeMatch挺重要的,因为@Autowired是按照类型注入的 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); } } } /** * Class representing injection information about an annotated method. */ private class AutowiredMethodElement extends InjectionMetadata.InjectedElement { private final boolean required; private volatile boolean cached = false; @Nullable private volatile Object[] cachedMethodArguments; public AutowiredMethodElement(Method method, boolean required, @Nullable PropertyDescriptor pd) { super(method, pd); this.required = required; } /** * 完成方法的注入 * @param bean * @param beanName * @param pvs * @throws Throwable */ @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 { // 获取方法的参数,从Spring 容器中获取(缓存中没有则尝试创建) 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; } 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(); } } } @Nullable private Object[] resolveCachedArguments(@Nullable String beanName) { Object[] cachedMethodArguments = this.cachedMethodArguments; if (cachedMethodArguments == null) { return null; } Object[] arguments = new Object[cachedMethodArguments.length]; for (int i = 0; i < arguments.length; i++) { arguments[i] = resolvedCachedArgument(beanName, cachedMethodArguments[i]); } return arguments; } } /** * DependencyDescriptor variant with a pre-resolved target bean name. */ @SuppressWarnings("serial") private static class ShortcutDependencyDescriptor extends DependencyDescriptor { private final String shortcut; private final Class requiredType; public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcut, Class requiredType) { super(original); this.shortcut = shortcut; this.requiredType = requiredType; } @Override public Object resolveShortcut(BeanFactory beanFactory) { return beanFactory.getBean(this.shortcut, this.requiredType); } } }

你可能感兴趣的:(#,Spring流程图,java,spring,后端)