美文网首页
spring-源码05-@Autowired实现原理

spring-源码05-@Autowired实现原理

作者: Coding626 | 来源:发表于2020-11-30 09:03 被阅读0次

    目的

    前四篇文章主要讲了spring ioc加载bean、实例化bean的主流程,其实每个主流程中会有很多分支流程,有许多分支流程是非常重要的,本文以最熟悉的@Autowired注解入手,切入主要的分支流程,也就是部分bean的后置处理器调用。对AOP深入学习有很大帮助。

    @Autowired作用

    众所周知,在日常开发中,我们如果要使用某个bean,前提当然是该bean在spring容器中,直接使用@Autowired即可,不需要一个一个new,并且spring会将依赖关系的bean也给我们创建好,这样就省了我们很多事情。

    那么@Autowired是如何实现的自动注入的?

    @Autowired实现原理

    1.doCreateBean创建bean

    上文说到了spring在创建bean的时候会进入AbstractAutowireCapableBeanFactory.doCreateBean,然后调用createBeanInstance方法初始实例化对象,这个时候还没有赋值,@Autowired操作属于赋值操作,因为是要给当前对象的属性赋值,所以该逻辑还不会对@Autowired进行任何操作。

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
            // Instantiate the bean.
            BeanWrapper instanceWrapper = null;
            if (mbd.isSingleton()) {
                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
            }
            if (instanceWrapper == null) {
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
            final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
            Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    
            // Allow post-processors to modify the merged bean definition.
            synchronized (mbd.postProcessingLock) {
                if (!mbd.postProcessed) {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                    mbd.postProcessed = true;
                }
            }
    
            // Eagerly cache singletons to be able to resolve circular references
            // even when triggered by lifecycle interfaces like BeanFactoryAware.
            boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                    isSingletonCurrentlyInCreation(beanName));
            if (earlySingletonExposure) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Eagerly caching bean '" + beanName +
                            "' to allow for resolving potential circular references");
                }
                addSingletonFactory(beanName, new ObjectFactory<Object>() {
                    public Object getObject() throws BeansException {
                        return getEarlyBeanReference(beanName, mbd, bean);
                    }
                });
            }
    
            // Initialize the bean instance.
            Object exposedObject = bean;
            try {
                populateBean(beanName, mbd, instanceWrapper);
                if (exposedObject != null) {
                    exposedObject = initializeBean(beanName, exposedObject, mbd);
                }
            }
            catch (Throwable ex) {
                if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                    throw (BeanCreationException) ex;
                }
                else {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
                }
            }
    
            if (earlySingletonExposure) {
                Object earlySingletonReference = getSingleton(beanName, false);
                if (earlySingletonReference != null) {
                    if (exposedObject == bean) {
                        exposedObject = earlySingletonReference;
                    }
                    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                        String[] dependentBeans = getDependentBeans(beanName);
                        Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                        for (String dependentBean : dependentBeans) {
                            if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                                actualDependentBeans.add(dependentBean);
                            }
                        }
                        if (!actualDependentBeans.isEmpty()) {
                            throw new BeanCurrentlyInCreationException(beanName,
                                    "Bean with name '" + beanName + "' has been injected into other beans [" +
                                    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                    "] in its raw version as part of a circular reference, but has eventually been " +
                                    "wrapped. This means that said other beans do not use the final version of the " +
                                    "bean. This is often the result of over-eager type matching - consider using " +
                                    "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                        }
                    }
                }
            }
    
            // Register bean as disposable.
            try {
                registerDisposableBeanIfNecessary(beanName, bean, mbd);
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
            }
    
            return exposedObject;
        }
    

    2.@Autowired注解预解析

    上图源码中,调用了applyMergedBeanDefinitionPostProcessors方法

                if (!mbd.postProcessed) {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                    mbd.postProcessed = true;
                }
    

    点进去看调用了bdp.postProcessMergedBeanDefinition,

    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof MergedBeanDefinitionPostProcessor) {
                    MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                    bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
                }
            }
        }
    

    进入AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition,再进去findAutowiringMetadata->buildAutowiringMetadata

    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
            if (beanType != null) {
                InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
                metadata.checkConfigMembers(beanDefinition);
            }
        }
    

    这里 findAutowiredAnnotation会去找@Autowire和@Value进行解析到元数据中。

    private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
            LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
            Class<?> targetClass = clazz;
    
            do {
                LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
                for (Field field : targetClass.getDeclaredFields()) {
                    Annotation ann = findAutowiredAnnotation(field);
                    if (ann != null) {
                        if (Modifier.isStatic(field.getModifiers())) {
                            if (logger.isWarnEnabled()) {
                                logger.warn("Autowired annotation is not supported on static fields: " + field);
                            }
                            continue;
                        }
                        boolean required = determineRequiredStatus(ann);
                        currElements.add(new AutowiredFieldElement(field, required));
                    }
                }
    
    
    @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.
            }
        }
    
    

    我这里创建了一个Car类,里面定义了一个User对象属性

    @Component
    @Login(name="name1",times=6)
    public class Car {
    
        private String name="bmw";
        
        private String type;
    
        @Autowired
        User user;
    
    

    这里可以看到在初始化Car类的时候,在这个方法中初始化属性,会将属性User对象进行预处理


    1 (2).png
    2.png
    3.png

    3.populateBean对属性进行赋值

    该方法上一篇文章写了,是对bean里面的属性进行赋值操作,也就是@Autowire实现的重头戏

    3.1后置处理器调用,处理依赖对象

    在AbstractAutowireCapableBeanFactory.populateBean方法中调用了bean的后置处理器的 ibp.postProcessPropertyValues方法

      for (BeanPostProcessor bp : getBeanPostProcessors()) {
                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                            
                            pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                            if (pvs == null) {
                                return;
                            }
                        }
                    }
    

    上面会有很多bean后置处理器,我们只看AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues

    @Override
        public PropertyValues postProcessPropertyValues(
                PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
    
            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然后调用AutowiredAnnotationBeanPostProcessor.inject,再点进去beanFactory.resolveDependency->doResolveDependency真正的对依赖进行解析

    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());
                    return (descriptor.getField() != null ?
                            converter.convertIfNecessary(value, type, descriptor.getField()) :
                            converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
                }
    
                
                Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
                if (multipleBeans != null) {
                    return multipleBeans;
                }
                
                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) {
                    
                    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 {
                    
                    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);
            }
        }
    

    然后 调用了findAutowireCandidates,找到真正的注解候选bean

    protected Map<String, Object> findAutowireCandidates(
                String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
    
            String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this, requiredType, true, descriptor.isEager());
            Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
            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 candidateName : candidateNames) {
                if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) {
                    result.put(candidateName, getBean(candidateName));
                }
            }
            return result;
        }
    

    看下图,当前的beanName为Car,Car.User会去spring容器中调用getBean(“user”)方法中去初始化User对象,又回到1步骤中。


    4.png
    5..png

    最后,执行之前的重复步骤,最终设置到bean中

    6.png

    总结

    @Autowird核心实现类AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues,是spring bean的一个后置处理器,运用次扩展点切入实现@Autowird注入对象逻辑

    相关文章

      网友评论

          本文标题:spring-源码05-@Autowired实现原理

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