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; } }
- Spring IOC原理源码解析(@Autowired原理详解 :标识属性与方法)(二 )
- Spring IOC原理源码解析(@Autowired原理详解 :标识构造函数)(一 )
- spring源码解析-IOC原理
- spring源码学习之路---IOC实现原理(二)
- Spring IOC原理解析
- spring ioc原理解析
- Spring IOC原理与源码分析
- 详解Spring IOC 与 DI 核心原理
- SPRING技术内幕:深入解析SPRING架构与设计原理(第2版)-笔记(二)IOC注入
- 浅谈Spring(二)IOC原理
- spring学习(二):ioc原理
- 源码解读Spring IOC原理
- 源码解读Spring IOC原理
- 源码解读Spring IOC原理
- 源码解读Spring IOC原理
- Spring:源码解读IOC原理
- spring培训第一讲-ioc实现原理源码解析
- spring ioc 源码解析(二)
- linux下dlib库的安装
- Fiddler抓包5-接口测试(Composer)
- MATLAB Floor 用法
- 用python验证Android签名机制
- centos7-codis安装部署,解决redis分布式的方案
- Spring IOC原理源码解析(@Autowired原理详解 :标识属性与方法)(二 )
- cannot lock ref问题的解决
- C#常用的访问修饰符
- java基于redis客户端redisson的RPC远程服务调用
- 新手学习mybatis总结
- 【数据结构】【C】顺序栈
- 技术分享连载(四十三)
- python3 使用 fabric3 模块实现密钥登录远程主机
- MFC中用c++语言对配置文件操作(读、写)