美文网首页
AutowiredAnnotaionBeanProcessor

AutowiredAnnotaionBeanProcessor

作者: 何德何能者 | 来源:发表于2021-01-05 18:43 被阅读0次

    AutowiredAnnotationBeanPostProcessor 是BeanPostProcessor的实现类, 用于处理autowired等关键注解

       /**
         * Create a new AutowiredAnnotationBeanPostProcessor
         * for Spring's standard {@link Autowired} annotation.
         * <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
         */
        @SuppressWarnings("unchecked")
        public AutowiredAnnotationBeanPostProcessor() {
            this.autowiredAnnotationTypes.add(Autowired.class);
            this.autowiredAnnotationTypes.add(Value.class);
            try {
                this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                        ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
                logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
            }
            catch (ClassNotFoundException ex) {
                // JSR-330 API not available - simply skip.
            }
        }
    

    实现beanPostProcessor的postProcessPropertyValues方法,执行属性填充

    @Override
        public PropertyValues postProcessPropertyValues(
                PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
                // 获取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;
        }
    

    findAutowiringMetadata方法查找出当前bean的所有需要注入的属性原数据,封装成InjectionMetadata对象。
    遍历需要注入的集合,执行注入

    public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
            Collection<InjectedElement> elementsToIterate =
                    (this.checkedElements != null ? this.checkedElements : this.injectedElements);
            if (!elementsToIterate.isEmpty()) {
                for (InjectedElement element : elementsToIterate) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Processing injected element of bean '" + beanName + "': " + element);
                    }
                    element.inject(target, beanName, pvs);
                }
            }
        }
    

    接着是单个属性注入

            @Override
            protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
                Field field = (Field) this.member;
                Object value;
                if (this.cached) {
                    // 除了spring 自身容器自动注入外,SpringBeanAutowiringSupport类可以手动触发自动注入,
                    // 所以如果同一个bean被多次触发注入就可以缓存依赖关系
                    value = resolvedCachedArgument(beanName, this.cachedFieldValue);
                }
                else {
                    // 构建依赖描述,即bean属性的依赖关系
                    DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
                    desc.setContainingClass(bean.getClass());
                    Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
                    TypeConverter typeConverter = beanFactory.getTypeConverter();
                    try {
                        // 解析并得到依赖对象(值)
                        value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                    }
                    catch (BeansException ex) {
                        throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
                    }
                    synchronized (this) {
                        if (!this.cached) {
                            if (value != null || this.required) {
                                this.cachedFieldValue = desc;
                                // 保存依赖关系到beanFactory
                                registerDependentBeans(beanName, autowiredBeanNames);
                                if (autowiredBeanNames.size() == 1) {
                                    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);
                }
            }
    

    依赖注入解析

    @Override
        public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
                Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException 
            // 是否是方法级别的注入,是的话要持有真实的参数名称(代码编译后可能参数名被改变)
            descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
            if (javaUtilOptionalClass == descriptor.getDependencyType()) {
                return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
            }
            else if (ObjectFactory.class == descriptor.getDependencyType() ||
                    ObjectProvider.class == descriptor.getDependencyType()) {
                // 如果注入的是ObjectFacoty或者ObjectProvider对象,则每次都注入新的
                return new DependencyObjectProvider(descriptor, requestingBeanName);
            }
            else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
                return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
            }
            else {
                // 如果是懒依赖,则给先生成一个代理对象,真实用到在从代理对象里获取
                Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                        descriptor, requestingBeanName);
                if (result == null) {
                    // 执行依赖注入
                    result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
                }
                return result;
            }
        }
    
    public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
                Set<String> autowiredBeanNames, 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();
               // 解析可能的值,如@Value()的表达式字符串
                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);
                        // 解析el表达式 (#{}这种)
                        value = evaluateBeanDefinitionString(strVal, bd);
                    }
                    TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
                    return (descriptor.getField() != null ?
                            converter.convertIfNecessary(value, type, descriptor.getField()) :
                            converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
                }
                  // 处理,数组,集合,map这三种类型的注入
                Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
                if (multipleBeans != null) {
                    return multipleBeans;
                }
                 // 获取可注入的候选bean
                Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
                if (matchingBeans.isEmpty()) {
                    if (isRequired(descriptor)) {
                        raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                    }
                    return null;
                }
    
                String autowiredBeanName;
                Object instanceCandidate;
    
                if (matchingBeans.size() > 1) {
              // 如果候选者多于一个,则根据
              // 1 首选有primary的
              // 2 根据order 排序倒叙,排前面的优先
              // 3 根据名称/别名进行匹配
                    autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                    if (autowiredBeanName == null) {
             //  多于一个候选者,但是确定不了是谁,则报错
                        if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                            return descriptor.resolveNotUnique(type, 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);
                }
              // 候选者是个class对象,则直接从beanFactory获取这个类型的对象实例
                return (instanceCandidate instanceof Class ?
                        descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
            }
            finally {
                ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
            }
        }
    

    再看看怎么查找注入候选bean的。

    protected Map<String, Object> findAutowireCandidates(
                String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
                  // 根据类型查找出已经定义的候选者的名称,包括非单例。
                 // 如果descriptor.isEager是true,则同时包括查询FactoryBean
            String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this, requiredType, true, descriptor.isEager());
            Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
                // 这里处理 可能注入是BeanFactory, ApplicationContext等spring内部对象
            for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
                if (autowiringType.isAssignableFrom(requiredType)) {
                    Object autowiringValue = this.resolvableDependencies.get(autowiringType);
                    autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
                    if (requiredType.isInstance(autowiringValue)) {
                        result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
                        break;
                    }
                }
            }
            for (String candidate : candidateNames) {
                            // 非自我引用 且 根据beanDefinition比较是候选者的都加入候选者集合
                if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
                    addCandidateEntry(result, candidate, descriptor, requiredType);
                }
            }
            if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
                // Consider fallback matches if the first pass failed to find anything...
                   // 没找到候选者,且要求注入对象不是集合,数组,map这些类型
                   // 则做退一步的打算,查找次要候选者
                DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
                for (String candidate : candidateNames) {
                    if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) {
                        addCandidateEntry(result, candidate, descriptor, requiredType);
                    }
                }
                if (result.isEmpty()) {
                    // Consider self references as a final pass...
                    // but in the case of a dependency collection, not the very same bean itself.
                    // 如果还是找不到候选者,则查找自己
                    for (String candidate : candidateNames) {
                        if (isSelfReference(beanName, candidate) &&
                                (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
                                isAutowireCandidate(candidate, fallbackDescriptor)) {
                            addCandidateEntry(result, candidate, descriptor, requiredType);
                        }
                    }
                }
            }
            return result;
        }
    

    流程走完

    总结

    bean的@Autowired @Value @Inject注解的解析是在AutowiredAnnotaionBeanProcessor完成的。
    每一个标识有以上注解的属性或者方法都会被封装成DependencyDescriptor对象,用于描述依赖关系。
    @Value 会解析上面的表达式或者el表达式,后直接赋值
    @Autowored和@Inject 或根据类型查询合适的候选者, 候选者可以是真实bean,也可以是代理对象。

    相关文章

      网友评论

          本文标题:AutowiredAnnotaionBeanProcessor

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