@Autowried注解处理流程解析

@Autowried注解由注解处理器AutowiredAnnotationBeanPostProcessor进行解析,AutowiredAnnotationBeanPostProcessor 同时还会处理@Value和JSR-330规范中的@Inject,如图

image.png

下面用示例代码来演示

public class DependencyResolutionDemo {

    @Autowired
    private User user;

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

        context.register(DependencyResolutionDemo.class);

        context.refresh();

        context.close();
    }
    
    @Bean
    public User user() {
        User user = new User();
        user.setId(2L);
        return user;
    }

}

Spring容器在启动时,会进行一系列的操作,在解析@Autowried注解时,会调用AutowiredAnnotationBeanPostProcessor#postProcessProperties 这个方法

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 因为要对 DependencyResolutionDemo这个对象进行解析,所以
        // 此时的bean就是 DependencyResolutionDemo 这个对象,beanName为dependencyResolutionDemo

        // 这个方法是为了获取DependencyResolutionDemo对象内部有哪些需要注入的对象
        // 当前类需要注入一个User对象,所以metadata 内部存储的是User类型
        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;
}

跟随metadata.inject()方法,会跳到InjectionMetadata#inject()方法中

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
         // target 为DependencyResolutionDemo对象,beanName为dependencyResolutionDemo
        Collection checkedElements = this.checkedElements;
        Collection elementsToIterate =
                (checkedElements != null ? checkedElements : this.injectedElements);
        if (!elementsToIterate.isEmpty()) {
              // 遍历DependencyResolutionDemo中需要注入的对象,按顺序注入
            for (InjectedElement element : elementsToIterate) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Processing injected element of bean '" + beanName + "': " + element);
                }
                   // 此element对象是 AutowiredAnnotationBeanPostProcessor中的一个内部类,
                element.inject(target, beanName, pvs);
            }
        }
    }

AutowiredAnnotationBeanPostProcessor的内部类
AutowiredFieldElement#inject

    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;
        }

        @Override
        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            // 获取当前要注入的字段,User
            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 {
                       // 通过resolveDependency来获取User对象,然后赋值给 value,在代码最后会通过反射将
                       // 对象赋值到DependencyResolutionDemo的成员变量user中
                    value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                }
                catch (BeansException ex) {
                    throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
                }
                // 省略其他代码...
            }
            if (value != null) {
                // 通过反射将解析到的对象注入到target中
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }
        }
    }

beanFactory.resolveDependency实际调用的是 DefaultListableBeanFactory#resolveDependency

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

            // 省略其他代码...

            // 判断要注入的Bean是否为懒加载,如果是则返回一个代码对象
            Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                    descriptor, requestingBeanName);
            if (result == null) {
                 // 如果不是则获取真实对象
                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
            }
            return result;
    }


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();
            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()));
                }
            }
               // 解析要注入的Bean是否是容器类型,如数组,Collection,Map,如果是的话会将符合条件的        
              // Bean加入容器中,直接返回。如果要注入的成员是,List userlist这种,就会走这个方法
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
            if (multipleBeans != null) {
                return multipleBeans;
            }
              // 返回符合条件的BeanMap, key是Bean名称,value是Bean实例
            Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
              // 如果没有找到符合条件的Bean,并且@Autowored中的require = true会抛出 
             // NoSuchBeanDefinitionException 异常,     
            if (matchingBeans.isEmpty()) {
                if (isRequired(descriptor)) {
                    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                return null;
            }

            String autowiredBeanName;
            Object instanceCandidate;
            // 如果找到的Bean数量大于1,则会去查找标注了@Primary的那个Bean名称进行返回
            if (matchingBeans.size() > 1) {
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                 // 如果Bean没有被@Primay标记,则会抛出,NoUniqueBeanDefinitionException 
                if (autowiredBeanName == null) {
                    if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                        return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                    }
                    else {
                        // In case of an optional Collection/Map, silently ignore a non-unique case:
                        // possibly it was meant to be an empty collection of multiple regular beans
                        // (before 4.3 in particular when we didn't even look for collection beans).
                        return null;
                    }
                }
                instanceCandidate = matchingBeans.get(autowiredBeanName);
            }
            else {
                // 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);
        }
    }



 // 解析容器Bean,如果DependencyResolutionDemo 需要注入一个List user, 则此方法会返回所有符
//合条件的Bean
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
            @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) {

        final Class type = descriptor.getDependencyType();
          // 如果是Stream类型,则走此种方法
        if (descriptor instanceof StreamDependencyDescriptor) {
            Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            if (autowiredBeanNames != null) {
                autowiredBeanNames.addAll(matchingBeans.keySet());
            }
            Stream stream = matchingBeans.keySet().stream()
                    .map(name -> descriptor.resolveCandidate(name, type, this))
                    .filter(bean -> !(bean instanceof NullBean));
            if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
                stream = stream.sorted(adaptOrderComparator(matchingBeans));
            }
            return stream;
        }
               //  如果bean被包裹的数组中,则走此种方式
        else if (type.isArray()) {
            Class componentType = type.getComponentType();
            ResolvableType resolvableType = descriptor.getResolvableType();
            Class resolvedArrayType = resolvableType.resolve(type);
            if (resolvedArrayType != type) {
                componentType = resolvableType.getComponentType().resolve();
            }
            if (componentType == null) {
                return null;
            }
            Map matchingBeans = findAutowireCandidates(beanName, componentType,
                    new MultiElementDescriptor(descriptor));
            if (matchingBeans.isEmpty()) {
                return null;
            }
            if (autowiredBeanNames != null) {
                autowiredBeanNames.addAll(matchingBeans.keySet());
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
            if (result instanceof Object[]) {
                Comparator comparator = adaptDependencyComparator(matchingBeans);
                if (comparator != null) {
                    Arrays.sort((Object[]) result, comparator);
                }
            }
            return result;
        }
              // 如果是集合类型,并且使用的是接口类型接收,则用此种方式
              // 也就是说使用List user可以正常注入,使用ArrayList就无法注入
        else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
            Class elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
            if (elementType == null) {
                return null;
            }
            Map matchingBeans = findAutowireCandidates(beanName, elementType,
                    new MultiElementDescriptor(descriptor));
            if (matchingBeans.isEmpty()) {
                return null;
            }
            if (autowiredBeanNames != null) {
                autowiredBeanNames.addAll(matchingBeans.keySet());
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            Object result = converter.convertIfNecessary(matchingBeans.values(), type);
            if (result instanceof List) {
                Comparator comparator = adaptDependencyComparator(matchingBeans);
                if (comparator != null) {
                    ((List) result).sort(comparator);
                }
            }
            return result;
        }
          // 处理Map类型的方式
        else if (Map.class == type) {
            ResolvableType mapType = descriptor.getResolvableType().asMap();
            Class keyType = mapType.resolveGeneric(0);
            if (String.class != keyType) {
                return null;
            }
            Class valueType = mapType.resolveGeneric(1);
            if (valueType == null) {
                return null;
            }
            Map matchingBeans = findAutowireCandidates(beanName, valueType,
                    new MultiElementDescriptor(descriptor));
            if (matchingBeans.isEmpty()) {
                return null;
            }
            if (autowiredBeanNames != null) {
                autowiredBeanNames.addAll(matchingBeans.keySet());
            }
            return matchingBeans;
        }
        else {
            return null;
        }
    }






你可能感兴趣的:(@Autowried注解处理流程解析)