Spring IOC原理源码解析(@Autowired原理详解 :标识属性与方法)(二 )

来源:互联网 发布:2寸照片剪裁软件 编辑:程序博客网 时间:2024/06/06 15:35

源码推荐看这篇博客的时候打开Spring源码,一边看源码,一边看博客上代码的关键处的注释,这样能更好的理解Spring IOC的流程及内部实现和使用方法。如果你对IOC的原理有些了解,则这些注释能帮你更深入的理解其实现方式。

Spring容器在每个Bean实例化之后,调用AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法:

代码块1

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标识方法的参数,然后执行此方法。

代码块2

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()方法,开始注入属性或方法参数。

代码块3

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;        }    }
原创粉丝点击