@Autowired通过源码进行原理详解

各位看友,请注意,本文章篇幅很长,得耐心看,希望坚持。

IOC,inversion of control 控制反转,有时候也叫DI,dependency injection 依赖注入,是一种代码解耦的方式。

在一个类中定义一个属性,正常情况下需要在此类中有对此属性赋值的代码,如setter方法,或者在构造函数中赋值,因此类和属性之间的关系已经确定下来了,类和属性间就有了一定的耦合关系。而IOC的精髓就是解耦,类中没有显式的对属性的赋值代码,同时属性的实际类型和值在运行时有系统动态的赋值,Spring对IOC做了很大的扩展,使用者可以很灵活的控制注入的对象类型及值。

Spring内IOC的最直接体现就是@Autowired注解,最常用的方式就是表示在属性上,Spring容器在启动时会将容器内类型是标识了@Autowired的属性类型或者其子类,实现类的Bean通过反射的形式赋值给此属性,或者叫注入的此类中。

Spring中对@Autowired注解的解析是通过一个叫AutowiredAnnotationBeanPostProcessor的BeanPostProcessor(Bean的后处理器)来进行的。BeanPostProcessor负责Bean的一系列处理,实例化前后,初始化前后灯阶段执行相应方法,具体方法的执行顺序如下:

 

BeanPostPrecessors Invoke Procedure(执行流程)	

	
1.InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(Class<?> beanClass, String beanName);	
invoke before doCreateBean(),if the method returns not null,the return Object will as the Bean, avoid invoke doCreateBean() ;	

	
2.SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(Class<?> beanClass, String beanName);	
used to determine to use which Constructor to instance Bean;	

	
3.MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);	
the Bean gets instantiated, modify the RootBeanDefinition ,such as adding PropertyValue etc. before populate Bean;	

	
4.SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(Object bean, String beanName);	
invoke before populate Bean,used for resolve Circular Reference;	

	
5.InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(Object bean, String beanName);	
invoke in populate Bean, but before fill in values,return false will break the opreation for filling values in Bean;	

	
6.InstantiationAwareBeanPostProcessor.postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName);	
invoke in populate Bean, but before fill in values,modify the PropertyValues which will be apply for the Bean,	
return null will break the opreation for filling values in Bean;	

	
7.BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName);	
invoked before invokeInitMethods, modify the finally Bean instance	

	
8.BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName);	
invoked after invokeInitMethods, modify the finally Bean instance	

使用者可以自己定义自己的BeanPostProcessor,将其以Bean的形式注册到Spring容器中,Spring容器在启动时会执行其相应方法。

AutowiredAnnotationBeanPostProcessor在Spring容器初始化时会最先执行determineCandidateConstructors方法,先看起源码:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter	
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {	
        //此方法的含义是解析Bean类里构造函数上的@Autowired注解,如果有合适的标识了@Autowired的构造函数,	
        //则在实例化此Bean时会使用此构造函数,@Import和@ComponentScan得到的Bean会如此解析,	
        //@Bean标识方法生成的Bean不会如此	
        public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)	
            throws BeanCreationException {	

	
        // Let's check for lookup methods here..	
        if (!this.lookupMethodsChecked.contains(beanName)) {	
            try {	
                ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {	
                    @Override	
                    public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {	
                        Lookup lookup = method.getAnnotation(Lookup.class);	
                        if (lookup != null) {	
                            LookupOverride override = new LookupOverride(method, lookup.value());	
                            try {	
                                RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);	
                                mbd.getMethodOverrides().addOverride(override);	
                            }	
                            catch (NoSuchBeanDefinitionException ex) {	
                                throw new BeanCreationException(beanName,	
                                        "Cannot apply @Lookup to beans without corresponding bean definition");	
                            }	
                        }	
                    }	
                });	
            }	
            catch (IllegalStateException ex) {	
                throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);	
            }	
            catch (NoClassDefFoundError err) {	
                throw new BeanCreationException(beanName, "Failed to introspect bean class [" + beanClass.getName() +	
                        "] for lookup method metadata: could not find class that it depends on", err);	
            }	
            this.lookupMethodsChecked.add(beanName);	
        }	

	
        // Quick check on the concurrent map first, with minimal locking.	
        Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);	
        if (candidateConstructors == null) {	
            // Fully synchronized resolution now...	
            synchronized (this.candidateConstructorsCache) {	
                //对每个类的构造函数只解析一次,解析完会存储结果,以备下次服用	
                candidateConstructors = this.candidateConstructorsCache.get(beanClass);	
                if (candidateConstructors == null) {	
                    Constructor<?>[] rawCandidates;	
                    try {	
                        rawCandidates = beanClass.getDeclaredConstructors();	
                    }	
                    catch (Throwable ex) {	
                        throw new BeanCreationException(beanName,	
                                "Resolution of declared constructors on bean Class [" + beanClass.getName() +	
                                "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);	
                    }	
                    List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);	
                    Constructor<?> requiredConstructor = null;	
                    Constructor<?> defaultConstructor = null;	
                    for (Constructor<?> candidate : rawCandidates) {	
                        //查看构造函数上是否标识@Autowired注解,获取注解的属性	
                        AnnotationAttributes ann = findAutowiredAnnotation(candidate);	
                        if (ann == null) {	
                            Class<?> userClass = ClassUtils.getUserClass(beanClass);	
                            if (userClass != beanClass) {	
                                try {	
                                    Constructor<?> superCtor =	
                                            userClass.getDeclaredConstructor(candidate.getParameterTypes());	
                                    //如果此构造函数是重载了父类的构造函数,则寻找父类的构造函数,查看是否标识@Autowired注解,获取注解的属性	
                                    ann = findAutowiredAnnotation(superCtor);	
                                }	
                                catch (NoSuchMethodException ex) {	
                                    // Simply proceed, no equivalent superclass constructor found...	
                                }	
                            }	
                        }	
                        //当构造函数上存在@Autowired注解	
                        if (ann != null) {	
                            //@Autowired默认的required = true,当有一个required = true的@Autowired标识的构造函数时,	
                            //不能有其他的构造函数再标识@Autowired,否则会报错	
                            if (requiredConstructor != null) {	
                                throw new BeanCreationException(beanName,	
                                        "Invalid autowire-marked constructor: " + candidate +	
                                        ". Found constructor with 'required' Autowired annotation already: " +	
                                        requiredConstructor);	
                            }	
                            //@Autowired的required的属性值,true / false	
                            boolean required = determineRequiredStatus(ann);	
                            if (required) {	
                                if (!candidates.isEmpty()) {	
                                    throw new BeanCreationException(beanName,	
                                            "Invalid autowire-marked constructors: " + candidates +	
                                            ". Found constructor with 'required' Autowired annotation: " +	
                                            candidate);	
                                }	
                                requiredConstructor = candidate;	
                            }	
                            candidates.add(candidate);	
                        } 	
                        else if (candidate.getParameterTypes().length == 0) {	
                            defaultConstructor = candidate;	
                        }	
                    }	
                    if (!candidates.isEmpty()) {	
                        // Add default constructor to list of optional constructors, as fallback.	
                        当没有构造函数标识@Autowired时,设置默认的构造函数作为额外选择	
                        if (requiredConstructor == null) {	
                            if (defaultConstructor != null) {	
                                candidates.add(defaultConstructor);	
                            }  //如果没有默认的无参构造函数,且有@Autowired(required = false)的构造函数,则发出警告信	
                            else if (candidates.size() == 1 && logger.isWarnEnabled()) {	
                                logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +	
                                        "': single autowire-marked constructor flagged as optional - " +	
                                        "this constructor is effectively required since there is no " +	
                                        "default constructor to fall back to: " + candidates.get(0));	
                            }	
                        }	
                        candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);	
                    }  //若只有一个构造函数,且没标识@Autowired,其参数长度>0,将其作为候选者	
                    else if (rawCandidates.length == 1 && rawCandidates[0].getParameterTypes().length > 0) {	
                        candidateConstructors = new Constructor<?>[] {rawCandidates[0]};	
                    } //没有合适的构造函数	
                    else {	
                        candidateConstructors = new Constructor<?>[0];	
                    }	
                    this.candidateConstructorsCache.put(beanClass, candidateConstructors);	
                }	
            }	
        }	
        return (candidateConstructors.length > 0 ? candidateConstructors : null);	
    }	

	
}

AutowiredAnnotationBeanPostProcessor筛选@Autowired标识的构造函数的代码就是这些,筛选出这些构造函数之后,Spring使用ConstructorResolver这个类来择取合适的构造函数,流程如下:

首先对这些构造函数按修饰符优先public排序,修饰符相同再按参数的长短排序,最先解析参数最长的public修饰的构造函数,其优先级最高.

对构造函数的每一个参数解析,如果每一个参数均能从Spring容器中找到合适的Bean,则此将此构造函数作为最优解,如果容器内Bean不能满足所有参数,则解析下一个构造函数。

如果存在两个参数长度相同的构造函数,且容器内Bean均能满足参数解析,则按参数类型和Bean类型的差异性求取参数的差异权重,比如参数是接口,Bean是实现类,则差异加2,参数是集合,Bean是单个类,则转换成集合,差异加2等等,比较两个构造函数的差异权重大小,差异小的那个作为最优解。如果两个差异权重相等,则抛出含有模棱两可的构造函数的BeanCreationException。

当有了最优解的构造函数后,如果下一个构造函数的参数长度等于最优解,则解析此构造函数,如果参数长度小于最优解,则不再解析,直接忽略之后的所有构造函数。

当得到了构造函数最优解之后,将此构造函数存入此Bean的BeanDefinition中,以备下次复用,就是说只对构造函数候选者集合解析一次,下次实例化Bean的时候可以直接得到这个最优解。

以上的情况是基于Spring容器实例化Bean的情况,就是实例化时不会附带Arguments,就是不带参数,如果是使用者自己实例化Bean时,通过BeanFactory的 Object getBean(String name, Object… args) throws BeansException; T getBean(Class requiredType, Object… args) throws BeansException;方法实例化时,按照构造函数的顺序传入实例化参数,则Spring在找合适的构造函数时会忽略之前缓存的最优解,以同样的顺序解析构造函数候选者集合,看看哪些构造函数的参数适合传入的参数,找不到合适的则跑出BeanCreationException。

以上就是@Autowired注解在构造函数上的用法的原理及流程。

重点: BeanFactory的getBean()方法获取scope = singleton的Bean时,不会生成新的Bean对象, 

在scope为request及session的生命周期内,Bean的实例化只会触发一次,也就是说@Autowired的标识的构造函数不是每次调用getBean()均会触发执行。只有scope = prototype的Bean,才会每次均执行。

pring容器在每个Bean实例化之后,调用AutowiredAnnotationBeanPostProcessor的

postProcessMergedBeanDefinition方法:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter	
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {	
        @Override	
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {	
        if (beanType != null) {  //搜索每个Bean内@Autowired注解的信息	
            InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);	
            metadata.checkConfigMembers(beanDefinition);	
        }	
    }	

	
    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, 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.	
        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) {	
                        metadata.clear(pvs);	
                    }	
                    try {  //解析@Autowired注解的信息,生成元数据,缓存起来	
                        metadata = buildAutowiringMetadata(clazz);	
                        this.injectionMetadataCache.put(cacheKey, metadata);	
                    }	
                    catch (NoClassDefFoundError err) {	
                        throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +	
                                "] for autowiring metadata: could not find class that it depends on", err);	
                    }	
                }	
            }	
        }	
        return metadata;	
    }	

	
    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {	
        LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();	
        Class<?> targetClass = clazz;	

	
        do {	
            final LinkedList<InjectionMetadata.InjectedElement> currElements =	
                    new LinkedList<InjectionMetadata.InjectedElement>();	

	
            ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {	
                @Override	
                public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {	
                    //如果类内的属性上有@Autowired注解,则用工具类获取注解信息	
                    AnnotationAttributes ann = findAutowiredAnnotation(field);	
                    if (ann != null) {  //@Autowired注解不支持静态方法	
                        if (Modifier.isStatic(field.getModifiers())) {	
                            if (logger.isWarnEnabled()) {	
                                logger.warn("Autowired annotation is not supported on static fields: " + field);	
                            }	
                            return;	
                        }  //获取@Autowired注解的required的属性值,如果true,但注入失败会抛出异常,false则不会	
                        boolean required = determineRequiredStatus(ann);	
                        currElements.add(new **AutowiredFieldElement**(field, required));	
                    }	
                }	
            });	

	
            ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {	
                @Override	
                public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {	
                    Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);	
                    if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {	
                        return;	
                    }  //如果方法上有@Autowired注解,则获取注解信息	
                    AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);	
                    if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {	
                        //@Autowired不支持静态方法	
                        if (Modifier.isStatic(method.getModifiers())) {	
                            if (logger.isWarnEnabled()) {	
                                logger.warn("Autowired annotation is not supported on static methods: " + method);	
                            }	
                            return;	
                        }	
                        //@Autowired注解标识在方法上的目的就是将容器内的Bean注入到方法的参数中,没有参数就违背了初衷	
                        if (method.getParameterTypes().length == 0) {	
                            if (logger.isWarnEnabled()) {	
                                logger.warn("Autowired annotation should only be used on methods with parameters: " +	
                                        method);	
                            }	
                        }	
                        boolean required = determineRequiredStatus(ann);	
                        PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);	
                        currElements.add(new **AutowiredMethodElement**(method, required, pd));	
                    }	
                }	
            });	

	
            elements.addAll(0, currElements);	
            //在解析完Bean的类型之后,递归的解析其父类,将所有的@Autowired的属性和方法收集起来,	
            //且类的层级越高其属性会被越优先注入	
            **targetClass = targetClass.getSuperclass()**;	
        }	
        while (targetClass != null && targetClass != Object.class);	

	
        return new InjectionMetadata(clazz, elements);	
    }	

	
}

在将@Autowired注解的信息解析成元数据之后,缓存起来,以备复用,每一个类只解析一次。

在BeanPostProcessor的postProcessMergedBeanDefinition()方法执行之后,下一步就是执行postProcessPropertyValues()方法,AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues()方法就是从Spring IOC容器从找到合适的Bean,注入属性。找到合适的Bean,注入@Autowired标识方法的参数,然后执行此方法。

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter	
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {	

	
    @Override	
    public PropertyValues postProcessPropertyValues(	
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {	
        //从缓存中找到此类的@Autowired元数据,尝试注入。没有@Autowired则会略过	
        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;	
    }	
}

InjectionMetadata,持有待注入的元数据信息,执行inject()方法,开始注入属性或方法参数。

public class InjectionMetadata {	

	
    private static final Log logger = LogFactory.getLog(InjectionMetadata.class);	

	
    private final Class<?> targetClass;	
    //待注入的属性,是一个InjectedElement集合,按类等层级排列,父类的@Autowired排前	
    private final Collection<InjectedElement> injectedElements;	

	
    private volatile Set<InjectedElement> checkedElements;	

	

	
    public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {	
        this.targetClass = targetClass;	
        this.injectedElements = elements;	
    }	

	
    public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {	
        Collection<InjectedElement> elementsToIterate =	
                (this.checkedElements != null ? this.checkedElements : this.injectedElements);	
        if (!elementsToIterate.isEmpty()) {	
            boolean debug = logger.isDebugEnabled();	
            for (InjectedElement element : elementsToIterate) {	
                if (debug) {	
                    logger.debug("Processing injected element of bean '" + beanName + "': " + element);	
                }	
                //解析@Autowired注解生成的元数据类有AutowiredFieldElement,AutowiredMethodElement	
                //这两个类继承InjectionMetadata .InjectedElement,各自实现了inject方法。	
                //这两个类是AutowiredAnnotationBeanPostProcessor的私有内部类	
                element.inject(target, beanName, pvs);	
            }	
        }	
    }	
}

下面先看属性的注入:

代码块4

private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {	

	
        private final boolean required;	

	
        private volatile boolean cached = false;	

	
        private volatile Object cachedFieldValue;	

	
        public AutowiredFieldElement(Field field, boolean required) {	
            super(field, null);	
            this.required = required;	
        }	

	
        @Override	
        protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {	
            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<String>(1);	
                TypeConverter typeConverter = beanFactory.getTypeConverter();	
                try {	
                    //如果@Autowired标识的属性有一个合适的待注入对象,则缓存这个Bean的名称,	
                    //如果再次生成这个Bean时,就不需要重新按类型去搜索Spring容器,直接获取这个缓存Bean的名称	
                    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;	
                            //注册Bean依赖	
                            registerDependentBeans(beanName, autowiredBeanNames);	
                            if (autowiredBeanNames.size() == 1) {	
                                String autowiredBeanName = autowiredBeanNames.iterator().next();	
                                if (beanFactory.containsBean(autowiredBeanName)) {	
                                    //@Autowired标识属性类型和Bean的类型要匹配,因此Array,Collection,Map类型的属性不支持缓存属性Bean名称	
                                    if (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);  //通过反射为属性赋值	
            }	
        }	
    }

接下来就需要Spring IOC容器根据DependencyDescriptor依赖描述去寻找容器中合适的Bean:

代码块5

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory	
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {	

	
    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()) {	
            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();	
            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()));	
            }	
            //如果标识@Autowired注解的属性是容器类型,Array,Collection,Map,则在这个方法中解析,	
            //如果类型是容器类型,且返回了合适的Bean,则解析成功,代码详解请看此段代码的下一段代码	
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);	
            if (multipleBeans != null) { //如果确实时容器类型的属性,则直接返回	
                return multipleBeans;	
            }	
            //非容器类型属性,按类型去IOC容器内择取所有类型匹配的候选者	
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);	
            if (matchingBeans.isEmpty()) { //如果没有合适的Bean,但注解的required = true,则抛出异常,若required = false,则注入失败。	
                if (descriptor.isRequired()) {	
                    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);	
                }	
                return null;	
            }	

	
            String autowiredBeanName;	
            Object instanceCandidate;	

	
            if (matchingBeans.size() > 1) {	
                //非容器属性,但是有多个候选者,此时需要从中选出最优的那个,代码详解看代码块9	
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);	
                if (autowiredBeanName == null) {	
                    if (descriptor.isRequired() || !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);	
            }	
            return (instanceCandidate instanceof Class ?	
                    descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);	
        }	
        finally {	
            ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);	
        }	
    }	

	
}

Spring IOC容器解析Array,Collection,Map类型的属性注入:

代码块6

private Object resolveMultipleBeans(DependencyDescriptor descriptor, String beanName,	
            Set<String> autowiredBeanNames, TypeConverter typeConverter) {	

	
        Class<?> type = descriptor.getDependencyType();	
        if (type.isArray()) {  //如果@Autowired标识的是数组类型的属性	
            Class<?> componentType = type.getComponentType(); //获取数组的内容类型	
            ResolvableType resolvableType = descriptor.getResolvableType();	
            Class<?> resolvedArrayType = resolvableType.resolve();	
            if (resolvedArrayType != null && resolvedArrayType != type) {	
                type = resolvedArrayType;	
                componentType = resolvableType.getComponentType().resolve();	
            }	
            if (componentType == null) {	
                return null;	
            } //通过类型去IOC容器内择取符合的Bean都是使用这个方法,很重要,此方法请看此段代码的下一段	
            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());	
            //将得到的Bean的候选者们转换为属性类型,如从set转换为Array,List等	
            Object result = converter.convertIfNecessary(matchingBeans.values(), type);	
            if (getDependencyComparator() != null && result instanceof Object[]) {	
                Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));	
            }	
            return result;	
        }	
        else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {	
            //获取Collection的泛型	
            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 (getDependencyComparator() != null && result instanceof List) {	
                Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));	
            }	
            return result;	
        }	
        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;	
        }	
  }

Spring IOC容器通过类型到容器呢择取符合的Bean的方法:

代码块7

protected Map<String, Object> findAutowireCandidates(	
            String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {	
        //Spring容IOC容器中获取所有的符合类型的Bean,包括非Singleton的scope,	
        //也就是说request,session,prototype的均会被实例化,	
        //request,session如果此时被实例化会报异常,因为这两个作用域的Bean实际是存储在HttpRequest中的,	
        //此时还没有Http请求,如果是FactoryBean,则匹配getObject()放回的类型	
        String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(	
                this, requiredType, true, descriptor.isEager());	
        Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);	
        //首先从容器自身注册了的依赖解析来匹配,Spring容器自身注册了很多Bean的依赖,	
        //当使用者想要注入指定类型的Bean时,会优先从已注册的依赖内寻找匹配,这点很重要,代码详解请看此段下一段。	
        for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {	
            if (autowiringType.isAssignableFrom(requiredType)) {	
                Object autowiringValue = this.resolvableDependencies.get(autowiringType);	
                autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);	
                //如果注册的依赖Bean类型时指定类型的实例或是其父类,接口,则将其作为候选者,注册依赖的类型不会重复	
                if (requiredType.isInstance(autowiringValue)) {	
                    result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);	
                    break;	
                }	
            }	
        }	
        for (String candidate : candidateNames) {	
            //@Autowried标识的属性不能和定义其的类的类型相同,就是类不能再注入相同类,会触发无限递归注入	
            if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, 	
                addCandidateEntry(result, candidate, descriptor, requiredType);	
            }	
        }	
        if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {	
            // Consider fallback matches if the first pass failed to find anything...	
            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;	
    }	

	
        /**	
     * Add an entry to the candidate map: a bean instance if available or just the resolved	
     * type, preventing early bean initialization ahead of primary candidate selection.	
     */	
    private void addCandidateEntry(Map<String, Object> candidates, String candidateName,	
            DependencyDescriptor descriptor, Class<?> requiredType) {	
        //当@Autowired标识的是容器类型的属性,生成的依赖描述类型是MultiElementDescriptor ,	
        //因此所有的候选者均是合格的,所以会当场实例化他们。而如果属性的类型非容器,那么可能是多个候选者中挑一个,	
        //此时实例化他们所有就不合适了,最终会把合格的那个实例化,如果没有合格的则不实例化,	
        //提前实例化对Bean的很多方面有影响,比如AOP,EarlyReference等 */	
        if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) {	
            candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this));	
        }	
        else {	
            candidates.put(candidateName, getType(candidateName));	
        }	
    }

如下代码所示,Spring在开始实例化Bean之前,已经注册了很多Bean的历依赖关系对,当@Autowired标识的属性类型是已经注册了的依赖类型,则将这些注册的对象作为候选者。这些对象并不一定是容器内的Bean,比如Http请求相关的对象,他们被注入的优先级比容器内Bean高。同时也忽略了一些依赖关系,也就是有些类型的Bean不允许被注入,这个实现方式稍后会看到

代码块8

public abstract class AbstractApplicationContext extends DefaultResourceLoader	
        implements ConfigurableApplicationContext, DisposableBean {	

	
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {	
        // Tell the internal bean factory to use the context's class loader etc.	
        beanFactory.setBeanClassLoader(getClassLoader());	
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));	
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));	

	
        // Configure the bean factory with context callbacks.	
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));	
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);	
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);	
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);	
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);	
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);	
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);	

	
        // BeanFactory interface not registered as resolvable type in a plain factory.	
        // MessageSource registered (and found for autowiring) as a bean.	
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);	
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);	
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);	
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);	
    }	
}	

	
public abstract class WebApplicationContextUtils {	

	
        public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, ServletContext sc) {	
        beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());	
        beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope(false));	
        beanFactory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, new SessionScope(true));	
        if (sc != null) {	
            ServletContextScope appScope = new ServletContextScope(sc);	
            beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);	
            // Register as ServletContext attribute, for ContextCleanupListener to detect it.	
            sc.setAttribute(ServletContextScope.class.getName(), appScope);	
        }	

	
        beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());	
        beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());	
        beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());	
        beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());	
        if (jsfPresent) {	
            FacesDependencyRegistrar.registerFacesDependencies(beanFactory);	
        }	
    }	

	
}

普通属性输入,但是候选者有多个,如何从中挑选出最优解.

代码块9

protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {	
        Class<?> requiredType = descriptor.getDependencyType();	
        //根据@Primary注解来择取最优解	
        String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);	
        if (primaryCandidate != null) {	
            return primaryCandidate;	
        }	
        //根据@Order,@PriorityOrder,及实现Order接口的序号来择取最优解	
        String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);	
        if (priorityCandidate != null) {	
            return priorityCandidate;	
        }	
        // Fallback	
        for (Map.Entry<String, Object> entry : candidates.entrySet()) {	
            String candidateName = entry.getKey();	
            Object beanInstance = entry.getValue();	

	
            //如果通过以上两步都不能选择出最优解,则使用最基本的策略	
            //首先如果这个类型已经由Spring注册过依赖关系对,则直接使用注册的对象,	
            //候选者集合是LinkedHashMap,有序Map集合,容器注册的依赖对象位于LinkedHashMap的起始位置	
            //如果没有注册过此类型的依赖关系,则根据属性的名称来匹配,、	
            //如果属性名称和某个候选者的Bean名称或别名一致,那么直接将此Bean作为最优解	
            if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||	
                    matchesBeanName(candidateName, descriptor.getDependencyName())) {	
                return candidateName;	
            }	
        }	
        return null;	
    }	

	

	
    protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {	
        String primaryBeanName = null;	
        for (Map.Entry<String, Object> entry : candidates.entrySet()) {	
            String candidateBeanName = entry.getKey();	
            Object beanInstance = entry.getValue();	
            //候选者可以是父容器内的标识了@Primary的Bean,也可以是当前容器的。SpringMVC容器将Spring容器作为父容器	
            if (isPrimary(candidateBeanName, beanInstance)) {	
                if (primaryBeanName != null) {	
                    boolean candidateLocal = containsBeanDefinition(candidateBeanName);	
                    boolean primaryLocal = containsBeanDefinition(primaryBeanName);	
                    //此处确保同一个容器中同一个类型的多个Bean最多只有一个Bean标识了@Primary	
                    if (candidateLocal && primaryLocal) {	
                        throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),	
                                "more than one 'primary' bean found among candidates: " + candidates.keySet());	
                    }	
                    //如果上一个@Primary的Bean是父容器的,则用当前容器的候选者覆盖之前的@Primary的Bean	
                    else if (candidateLocal) {	
                        primaryBeanName = candidateBeanName;	
                    }	
                }	
                else {	
                    primaryBeanName = candidateBeanName;	
                }	
            }	
        }	
        return primaryBeanName;	
    }	

	
    protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {	
        String highestPriorityBeanName = null;	
        Integer highestPriority = null;	
        for (Map.Entry<String, Object> entry : candidates.entrySet()) {	
            String candidateBeanName = entry.getKey();	
            Object beanInstance = entry.getValue();	
            Integer candidatePriority = getPriority(beanInstance);	
            if (candidatePriority != null) {	
                if (highestPriorityBeanName != null) {	
                    //不能同时存在两个最高优先级的序号	
                    if (candidatePriority.equals(highestPriority)) {	
                        throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),	
                                "Multiple beans found with the same priority ('" + highestPriority +	
                                "') among candidates: " + candidates.keySet());	
                    } //使用优先级序号最小的Bean作为最优解	
                    else if (candidatePriority < highestPriority) {	
                        highestPriorityBeanName = candidateBeanName;	
                        highestPriority = candidatePriority;	
                    }	
                }	
                else {	
                    highestPriorityBeanName = candidateBeanName;	
                    highestPriority = candidatePriority;	
                }	
            }	
        }	
        return highestPriorityBeanName;	
    }

@Autowired标识方法的解析过程和标识属性类似,代码详解如下:

private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {	

	
        private final boolean required;	

	
        private volatile boolean cached = false;	

	
        private volatile Object[] cachedMethodArguments;	

	
        public AutowiredMethodElement(Method method, boolean required, PropertyDescriptor pd) {	
            super(method, pd);	
            this.required = required;	
        }	

	
        @Override	
        protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {	
            if (checkPropertySkipping(pvs)) {	
                return;	
            }	
            Method method = (Method) this.member;	
            Object[] arguments;	
            if (this.cached) { //如果已经解析过,且缓存了方法的参数注入,则不需要再次解析	
                // Shortcut for avoiding synchronization...	
                arguments = resolveCachedArguments(beanName);	
            }	
            else {	
                Class<?>[] paramTypes = method.getParameterTypes();	
                arguments = new Object[paramTypes.length];	
                DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];	
                Set<String> autowiredBeans = new LinkedHashSet<String>(paramTypes.length);	
                TypeConverter typeConverter = beanFactory.getTypeConverter();	
                for (int i = 0; i < arguments.length; i++) {	
                    MethodParameter methodParam = new MethodParameter(method, i);	
                    DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);	
                    currDesc.setContainingClass(bean.getClass());	
                    descriptors[i] = currDesc;	
                    try { //根据参数类型从Spring容器中寻找合适的Bean	
                        Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);	
                        //如果参数解析失败,但是required = false,则忽略执行此方法	
                        if (arg == null && !this.required) {	
                            arguments = null;	
                            break;	
                        }	
                        arguments[i] = arg;	
                    }	
                    catch (BeansException ex) {	
                        throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);	
                    }	
                }	
                synchronized (this) {	
                    if (!this.cached) {	
                        if (arguments != null) {	
                            this.cachedMethodArguments = new Object[paramTypes.length];	
                            for (int i = 0; i < arguments.length; i++) {	
                                this.cachedMethodArguments[i] = descriptors[i];	
                            }	
                            registerDependentBeans(beanName, autowiredBeans);	
                            if (autowiredBeans.size() == paramTypes.length) {	
                                Iterator<String> it = autowiredBeans.iterator();	
                                for (int i = 0; i < paramTypes.length; i++) {	
                                    String autowiredBeanName = it.next();	
                                    if (beanFactory.containsBean(autowiredBeanName)) {	
                                        if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {	
                                            this.cachedMethodArguments[i] = new ShortcutDependencyDescriptor(	
                                                    descriptors[i], autowiredBeanName, paramTypes[i]);	
                                        }	
                                    }	
                                }	
                            }	
                        }	
                        else {	
                            this.cachedMethodArguments = null;	
                        }	
                        this.cached = true;	
                    }	
                }	
            }	
            if (arguments != null) {	
                try {	
                    ReflectionUtils.makeAccessible(method);	
                    //参数解析完毕,执行此方法。@Autowired标识的方法执行的比@PostConstruct早	
                    method.invoke(bean, arguments);  	
                }	
                catch (InvocationTargetException ex){	
                    throw ex.getTargetException();	
                }	
            }	
        }	

	
        private Object[] resolveCachedArguments(String beanName) {	
            if (this.cachedMethodArguments == null) {	
                return null;	
            }	
            Object[] arguments = new Object[this.cachedMethodArguments.length];	
            for (int i = 0; i < arguments.length; i++) {	
                arguments[i] = resolvedCachedArgument(beanName, this.cachedMethodArguments[i]);	
            }	
            return arguments;	
        }	
    }

完毕,还是很长的,没看懂的可以重头再看。

640?wx_fmt=gif

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值