参考文献

@Autowired

1
2
3
4
5
6
7
8
9
10
11
12
13
// org.springframework.beans.factory.annotation.Autowired
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;

}

使用场景

@Autowired标注在构造器上,通过构造器注入依赖对象
@Autowired标注在方法上,通过方法注入依赖的对象
@Autowired标注在setter方法上,通过setter方法注入
@Autowired标注在方法参数上
@Autowired用在字段上
@Autowired标注字段,多个候选者的时候,按字段名称注入
将指定类型的所有bean,注入到Collection、Map中

@Autowire源码分析

  • @Autowired注解的原理用一句话讲明:就是先从IoC容器中根据类型找到所有符合的Bean,然后再根据@Primary、@Order、@PriorityOrder或Spring默认规则挑选出最符合的Bean,利用反射注入到字段中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /**
    * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
    * standard {@link Autowired @Autowired} and {@link Value @Value} annotations.
    * <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
    * if available.
    */
    @SuppressWarnings("unchecked")
    public AutowiredAnnotationBeanPostProcessor() {
    // 后置处理器将处理@Autowire注解
    this.autowiredAnnotationTypes.add(Autowired.class);
    // 后置处理器将处理@Value注解
    this.autowiredAnnotationTypes.add(Value.class);
    try {
    // 后置处理器将处理javax.inject.Inject JSR-330注解
    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.
    }
    }
    1
    按类型找->通过限定符@Qualifier过滤->@Primary->@Priority->根据名称找(字段名称或者参数名称)
    • 先按类型找,然后按名称找

触发方式

  • Spring容器在每个Bean实例化之后,调用AutowiredAnnotationBeanPostProcessorpostProcessMergedBeanDefinition方法,查找该Bean是否有@Autowired注解。

    1
    2
    3
    4
    5
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
    }
  • Spring在每个Bean实例化的时候,调用populateBean进行属性注入的时候,即调用postProcessProperties方法,查找该Bean是否有@Autowired注解。

    1
    2
    3
    4
    5
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
    --> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
    --> org.springframework.beans.factory.annotation.InjectionMetadata#inject
    --> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
    --> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
    /**
    * 该方法就是在属性注入populateBean中调用的pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); 的具体实现之一。
    * @param pvs the property values that the factory is about to apply (never {@code null})
    * @param bean the bean instance created, but whose properties have not yet been set
    * @param beanName the name of the bean
    * @return
    */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 获取指定类中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;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
    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.
    // 首先从容器中查找是否有给定类的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) {
    // 解析给定类autowire相关注解元信息
    metadata.clear(pvs);
    }
    // 解析给定类autowire相关注解元信息
    metadata = buildAutowiringMetadata(clazz);
    // 将得到的给定类autowire相关注解元信息存储在容器缓存中
    this.injectionMetadataCache.put(cacheKey, metadata);
    }
    }
    }
    return metadata;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 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()) {
    // 遍历每个字段 注入
    for (InjectedElement element : elementsToIterate) {
    element.inject(target, beanName, pvs);
    }
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
    @Override
    protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // 获取要注入的字段
    Field field = (Field) this.member;
    Object value;
    // 如果字段的值有缓存
    if (this.cached) {
    try {
    // 从缓存中获取字段值value
    value = resolvedCachedArgument(beanName, this.cachedFieldValue);
    }
    catch (NoSuchBeanDefinitionException ex) {
    // Unexpected removal of target bean for cached argument -> re-resolve
    value = resolveFieldValue(field, bean, beanName);
    }
    }
    // 没有缓存
    else {
    value = resolveFieldValue(field, bean, beanName);
    }
    // 如果字段值不为null
    if (value != null) {
    // 显式使用JDK的反射机制,设置自动的访问控制权限为允许访问
    ReflectionUtils.makeAccessible(field);
    // 为字段赋值
    field.set(bean, value);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    // org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject
    @Override
    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) {
    try {
    // 获取缓存中指定Bean名称的方法参数
    arguments = resolveCachedArguments(beanName);
    }
    catch (NoSuchBeanDefinitionException ex) {
    // Unexpected removal of target bean for cached argument -> re-resolve
    arguments = resolveMethodArguments(method, bean, beanName);
    }
    }
    // 如果没有缓存
    else {
    arguments = resolveMethodArguments(method, bean, beanName);
    }
    // 如果方法参数依赖对象不为null
    if (arguments != null) {
    try {
    // 使用JDK的反射机制,显式设置方法的访问控制权限为允许访问
    ReflectionUtils.makeAccessible(method);
    // 调用Bean的指定方法
    method.invoke(bean, arguments);
    }
    catch (InvocationTargetException ex) {
    throw ex.getTargetException();
    }
    }
    }
  • 最核心的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    @Nullable
    public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
    @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    // 注入点
    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    try {
    // 针对给定的工厂给定一个快捷实现的方式,例如考虑一些预先解析的信息
    // 在进入所有bean的常规类型匹配算法之前,解析算法将首先尝试通过此方法解析快捷方式。
    // 子类可以覆盖此方法
    Object shortcut = descriptor.resolveShortcut(this);
    if (shortcut != null) {
    return shortcut;
    }
    // 获取字段属性的类型
    Class<?> type = descriptor.getDependencyType();
    // 用于支持Spring的注解@Value
    // org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver.getSuggestedValue
    Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
    if (value != null) {
    if (value instanceof String) {
    // 解析Value值
    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 {
    // 通过转换器将bean的值转换为对应的type类型
    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()));
    }
    }
    // 如果标识@Autowired注解的属性是复合类型,如Array,Collection,Map
    // 从这个方法获取@Autowired里的
    Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
    if (multipleBeans != null) {
    return multipleBeans;
    }
    // 根据属性类型找到BeanFactory中所有类型的匹配bean
    // 返回值的构成: key=匹配的beanName,value=beanName对应的实例化后的bean(通过getBean(beanName)返回)
    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
    // 如果没有符合该类型的Bean
    if (matchingBeans.isEmpty()) {
    // 没有找到,检验 @Autowired的require是否为true
    if (isRequired(descriptor)) {
    // 抛出异常
    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
    }
    return null;
    }

    String autowiredBeanName;
    Object instanceCandidate;
    // 如果符合该类型的Bean有多个
    if (matchingBeans.size() > 1) {
    // 选出优先级最高的依赖
    autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
    if (autowiredBeanName == null) {
    // 判断是否必须注入 isRequired(descriptor)
    // 或者注解的属性类型并不是可以接受多个Bean的类型,如数组,Map,集合 !indicatesMultipleBeans(type)
    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 {
    // We have exactly one match.
    Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
    autowiredBeanName = entry.getKey();
    instanceCandidate = entry.getValue();
    }

    if (autowiredBeanNames != null) {
    autowiredBeanNames.add(autowiredBeanName);
    }
    if (instanceCandidate instanceof Class) {
    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);
    }
    }

@Qualifier

  • 可以在依赖注入查找候选者的过程中对候选者进行过滤

使用场景

用在类上
  • 用在类上,可以理解为给通过@Qulifier给这个bean打了一个标签。

    1
    2
    3
    4
    5
    6
    7
    import org.springframework.beans.factory.annotation.Qualifier; 
    import org.springframework.stereotype.Component;

    @Component
    @Qualifier("test1")
    public class TestClass {
    }
@Autowired结合@Qulifier指定注入的bean
  • 被注入的类型有多个的时候,可以使用@Qulifier来指定需要注入那个bean,将@Qulifiervalue设置为需要注入bean的名称

源码分析

  • 处理类

    1
    org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver
  • 入口方法

    1
    2
    3
    4
    5
    6
    org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveMultipleBeans
    --> org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates
    --> org.springframework.beans.factory.support.DefaultListableBeanFactory#isAutowireCandidate(java.lang.String, org.springframework.beans.factory.config.DependencyDescriptor)
    --> org.springframework.beans.factory.support.DefaultListableBeanFactory#isAutowireCandidate(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, org.springframework.beans.factory.config.DependencyDescriptor, org.springframework.beans.factory.support.AutowireCandidateResolver)
    --> org.springframework.beans.factory.support.AutowireCandidateResolver#isAutowireCandidate
    --> org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate

@Resource源码分析

  • 处理类

    1
    org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    static {
    resourceAnnotationTypes.add(Resource.class);

    webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
    if (webServiceRefClass != null) {
    resourceAnnotationTypes.add(webServiceRefClass);
    }

    ejbClass = loadAnnotationType("javax.ejb.EJB");
    if (ejbClass != null) {
    resourceAnnotationTypes.add(ejbClass);
    }
    }

@Autowired@Resource的区别

  • @Autowired@Resource都可以用来装配bean,都可以用于字段或setter方法。
  • @Autowired 默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许 null 值,可以设置它的 required 属性为 false。
  • @Resource 默认按名称装配,当找不到与名称匹配的bean时才按照类型进行装配。名称可以通过name属性指定,如果没有指定name属性,当注解写在字段上时,默认取字段名,当注解写在 setter 方法上时,默认取属性名进行装配。
    • 注意:如果name属性一旦指定,就只会按照名称进行装配。
  • @Resource 装配顺序
    • 如果同时指定name和 type,则从容器中查找唯一匹配的bean装配,找不到则抛出异常;
    • 如果指定name属性,则从容器中查找名称匹配的bean装配,找不到则抛出异常;
    • 如果指定 type 属性,则从容器中查找类型唯一匹配的bean装配,找不到或者找到多个抛出异常;
    • 如果不指定,则自动按照 byName 方式装配,如果没有匹配,则回退一个原始类型进行匹配,如果匹配则自动装配。