美文网首页
@Autowried注解处理流程解析

@Autowried注解处理流程解析

作者: 繁书_ | 来源:发表于2020-12-17 17:53 被阅读0次

    @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<InjectedElement> checkedElements = this.checkedElements;
            Collection<InjectedElement> 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<String> 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<String> 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<String> 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<user> userlist这种,就会走这个方法
                Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
                if (multipleBeans != null) {
                    return multipleBeans;
                }
                  // 返回符合条件的BeanMap, key是Bean名称,value是Bean实例
                Map<String, Object> 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<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);
            }
        }
    
    
    
     // 解析容器Bean,如果DependencyResolutionDemo 需要注入一个List<User> user, 则此方法会返回所有符
    //合条件的Bean
    private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
                @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
    
            final Class<?> type = descriptor.getDependencyType();
              // 如果是Stream类型,则走此种方法
            if (descriptor instanceof StreamDependencyDescriptor) {
                Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
                if (autowiredBeanNames != null) {
                    autowiredBeanNames.addAll(matchingBeans.keySet());
                }
                Stream<Object> 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<String, Object> 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<Object> comparator = adaptDependencyComparator(matchingBeans);
                    if (comparator != null) {
                        Arrays.sort((Object[]) result, comparator);
                    }
                }
                return result;
            }
                  // 如果是集合类型,并且使用的是接口类型接收,则用此种方式
                  // 也就是说使用List<User> user可以正常注入,使用ArrayList就无法注入
            else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
                Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
                if (elementType == null) {
                    return null;
                }
                Map<String, Object> 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<Object> 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<String, Object> 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注解处理流程解析

          本文链接:https://www.haomeiwen.com/subject/qwaagktx.html