Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)
在Spring源码深度解析(郝佳)-学习-源码解析-基于注解bean解析(一)博客中,己经对有注解的类进行了解析,得到了BeanDefinition,但是我们看到属性并没有封装到BeanDefinition(关于BeanDefinition的定义,这里不做过多的解释了,就是定义了Bean的属性,比如单例,多例,依赖,工厂方法,是否使用代理,等,而Bean的创建,是基于Bean的定义来的)中,而Bean创建的时候,是如何注入的呢?今天,我们带着这个问题,继续来跟踪基于注解的属性是如何注入。
先上示例。
Car.java
@Component @Data public class Car { private String color = "red"; }
Dog.java
@Component public class Dog { }
MyRequestAnnotation.java
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Service public @interface MyRequestAnnotation { String value() default ""; }
MyTestAnnotation.java
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component @Mapping @MyRequestAnnotation public @interface MyTestAnnotation { String name() default ""; @AliasFor("path") String[] value() default {}; RequestMethod[] method() default {}; }
User.java
@Service("xxxx") @MyTestAnnotation("/user/info") public class User { @Autowired private Car car; @Autowired private Dog dog; public void drive(){ System.out.println(car); } }
spring35_resource_inject_1.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.spring_1_100.test_31_40.test35_resource_inject.anno"/> </beans>
测试:
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_1_100/config_31_40/spring35_resource_inject_1.xml"); User user = (User) ac.getBean("xxxx"); user.drive(); }
结果输出:
而本篇博客的主要目的就是研究User对象中的car是如何注入的。
我们知道属性注入都是在Spring源码中的populateBean这个方法,那我们来测试一下,在这个方法之前和在这个方法之后打断点,看属性car有没有被注入进去。
在方法调用前,car和,dog都是空
方法调用后,car 和dog 都被实例化了。那我们就来重点分析 populateBean方法,其实Spring无论是xml配置的属性,还是通过注解依赖注入的属性,都是通过这个方法(populateBean)来进行属性填充的。
经过我不断的打断点,寻寻觅觅,竟然是通过AutowiredAnnotationBeanPostProcessor的postPropertyValues方法进行属性注入的。而AutowiredAnnotationBeanPostProcessor又是如何保存到AbstractBeanFactory的beanPostProcessors里的呢(因为在populateBean方法中调用了getBeanPostProcessors()方法,才得到所有的BeanPostProcessor,而getBeanPostProcessors()方法获取BeanPostProcessor是直接从AbstractBeanFactory的beanPostProcessors集合中取出来的)?带着好奇,我们来探索一番。因此,通过全局查找发现AutowiredAnnotationBeanPostProcessor.class关键字只在AnnotationConfigUtils的registerAnnotationConfigProcessors方法和AutowiredAnnotationBeanPostProcessor的构造函数中出现过,如下图所示,因此分别在这两处打上断点。
最终,我们发现AutowiredAnnotationBeanPostProcessor的BeanDefinition定义是在ComponentScanBeanDefinitionParser类的registerComponents方法处调用的。如下图,而ComponentScanBeanDefinitionParser这个类主要是Bean的注解解析时调用。
而AutowiredAnnotationBeanPostProcessor是在哪里调用创建的呢?继续跟踪断点。终于到了AutowiredAnnotationBeanPostProcessor的构造函数中。
从下图中可以看出,AutowiredAnnotationBeanPostProcessor的实例化是在refresh()方法的注册bean的处理器方法中调用。
PostProcessorRegistrationDelegate.java
private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List postProcessors) { for (BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); } }
AbstractBeanFactory.java
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); this.beanPostProcessors.remove(beanPostProcessor); this.beanPostProcessors.add(beanPostProcessor); if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { this.hasInstantiationAwareBeanPostProcessors = true; } if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { this.hasDestructionAwareBeanPostProcessors = true; } }
通过代码,最终,我们看到AutowiredAnnotationBeanPostProcessor被加入到beanPostProcessors中。到这里,我们知道了,在populateBean方法中,调用getBeanPostProcessors()方法时,能获取到AutowiredAnnotationBeanPostProcessor对象了。通过上面的铺垫,下面,我们来正式分析Spring是如何通过注解来进行属性注入的。
AutowiredAnnotationBeanPostProcessor.java
public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; } private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) { //从缓存中获取 String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); 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 { //缓存中不存在,直接构建metadata 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 { //找到当前属性的所有注解信息 AnnotationAttributes ann = findAutowiredAnnotation(field); if (ann != null) { if (Modifier.isStatic(field.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation is not supported on static fields: " + field); } return; } 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; } AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod); if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { if (Modifier.isStatic(method.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation is not supported on static methods: " + method); } return; } if (method.getParameterTypes().length == 0) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation should 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); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return new InjectionMetadata(clazz, elements); }
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) { for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) { AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type); if (attributes != null) { return attributes; } } return null; }
ReflectionUtils.java
public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) { //获取类的所有的属性 for (Field field : getDeclaredFields(clazz)) { try { fc.doWith(field); } catch (IllegalAccessException ex) { throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex); } } }
AutowiredAnnotationBeanPostProcessor.java
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) { //autowiredAnnotationTypes中是@Autowired和@Value注解,在AutowiredAnnotationBeanPostProcessor实例化时加入其中的 for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) { AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type); if (attributes != null) { return attributes; } } return null; }
AnnotatedElementUtils.java
public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, Class<? extends Annotation> annotationType) { Assert.notNull(annotationType, "annotationType must not be null"); return getMergedAnnotationAttributes(element, annotationType.getName()); } public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, String annotationName) { return getMergedAnnotationAttributes(element, annotationName, false, false); } public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { AnnotationAttributes attributes = searchWithGetSemantics(element, annotationName, new MergedAnnotationAttributesProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap)); AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes; } private static T searchWithGetSemantics(AnnotatedElement element, String annotationName, Processor processor) { try { return searchWithGetSemantics(element, annotationName, processor, new HashSet(), 0); } catch (Throwable ex) { AnnotationUtils.rethrowAnnotationConfigurationException(ex); throw new IllegalStateException("Failed to introspect annotations on " + element, ex); } } private static <T> T searchWithGetSemantics(AnnotatedElement element, String annotationName, Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) { Assert.notNull(element, "AnnotatedElement must not be null"); Assert.hasText(annotationName, "annotationName must not be null or empty"); //注解去重 if (visited.add(element)) { try { //获取属性上的所有注解 List<Annotation> declaredAnnotations = Arrays.asList(element.getDeclaredAnnotations()); T result = searchWithGetSemanticsInAnnotations(element, declaredAnnotations, annotationName, processor, visited, metaDepth); if (result != null) { return result; } List<Annotation> inheritedAnnotations = new ArrayList<Annotation>(); for (Annotation annotation : element.getAnnotations()) { if (!declaredAnnotations.contains(annotation)) { inheritedAnnotations.add(annotation); } } // Continue searching within inherited annotations result = searchWithGetSemanticsInAnnotations(element, inheritedAnnotations, annotationName, processor, visited, metaDepth); if (result != null) { return result; } } catch (Exception ex) { AnnotationUtils.handleIntrospectionFailure(element, ex); } } return null; } private static <T> T searchWithGetSemanticsInAnnotations(AnnotatedElement annotatedElement, List<Annotation> annotations, String annotationName, Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) { //递归遍历所有的注解 for (Annotation annotation : annotations) { //非java.lang.annotation包开头的注解,并且注解的名称为Autowired或者Value if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation) && (annotation.annotationType().getName().equals(annotationName) || metaDepth > 0)) { T result = processor.process(annotatedElement, annotation, metaDepth); if (result != null) { return result; } } } //主要是递归查找,比如Car car 属性配置了@MyAutowired注解,但是@MyAutowired又配置了@Autowired注解 for (Annotation annotation : annotations) { if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) { T result = searchWithGetSemantics(annotation.annotationType(), annotationName, processor, visited, metaDepth + 1); if (result != null) { processor.postProcess(annotatedElement, annotation, result); return result; } } } return null; }
MergedAnnotationAttributesProcessor.java
public AnnotationAttributes process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { boolean found = annotation.annotationType().getName().equals(this.annotationName); return (found ? AnnotationUtils.getAnnotationAttributes(annotatedElement, annotation, this.classValuesAsString, this.nestedAnnotationsAsMap, true) : null); }
AnnotationUtils.java
static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement, Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap, boolean mergeMode) { if (!mergeMode) { annotation = synthesizeAnnotation(annotation, annotatedElement); } Class<? extends Annotation> annotationType = annotation.annotationType(); AnnotationAttributes attrs = new AnnotationAttributes(annotationType); //获取注解的所有方法并遍历 for (Method method : getAttributeMethods(annotationType)) { try { //通过反射,获取注解配置的值 Object value = method.invoke(annotation); //获取注解配置的默认值 Object defaultValue = method.getDefaultValue(); if (mergeMode && (defaultValue != null)) { if (ObjectUtils.nullSafeEquals(value, defaultValue)) { //将值设置为Spring的默认值 value = DEFAULT_VALUE_PLACEHOLDER; } } attrs.put(method.getName(), adaptValue(annotatedElement, value, classValuesAsString, nestedAnnotationsAsMap)); } catch (Exception ex) { if (ex instanceof InvocationTargetException) { Throwable targetException = ((InvocationTargetException) ex).getTargetException(); rethrowAnnotationConfigurationException(targetException); } throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex); } } return attrs; }
当这个方法执行完毕后,我们得到Spring result是AnnotationAttributes。
我们再回到AnnotatedElementUtils的getMergedAnnotationAttributes方法中。
AnnotationUtils.java
static void postProcessAnnotationAttributes(AnnotatedElement element, AnnotationAttributes attributes, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { //属性是不是为空 if (attributes == null) { return; } Class<? extends Annotation> annotationType = attributes.annotationType(); //值是不是被替换 Set<String> valuesAlreadyReplaced = new HashSet<String>(); //注解的属性方法是否有别名 Map<String, List<String>> aliasMap = getAttributeAliasMap(annotationType); //如果有别名,将做别名相关的处理 for (String attributeName : aliasMap.keySet()) { if (valuesAlreadyReplaced.contains(attributeName)) { continue; } Object value = attributes.get(attributeName); boolean valuePresent = (value != null && value != DEFAULT_VALUE_PLACEHOLDER); for (String aliasedAttributeName : aliasMap.get(attributeName)) { if (valuesAlreadyReplaced.contains(aliasedAttributeName)) { continue; } Object aliasedValue = attributes.get(aliasedAttributeName); boolean aliasPresent = (aliasedValue != null && aliasedValue != DEFAULT_VALUE_PLACEHOLDER); // Something to validate or replace with an alias? if (valuePresent || aliasPresent) { if (valuePresent && aliasPresent) { // Since annotation attributes can be arrays, we must use ObjectUtils.nullSafeEquals(). if (!ObjectUtils.nullSafeEquals(value, aliasedValue)) { String elementAsString = (element != null ? element.toString() : "unknown element"); String msg = String.format("In AnnotationAttributes for annotation [%s] declared on [%s], " + "attribute [%s] and its alias [%s] are declared with values of [%s] and [%s], " + "but only one declaration is permitted.", annotationType.getName(), elementAsString, attributeName, aliasedAttributeName, ObjectUtils.nullSafeToString(value), ObjectUtils.nullSafeToString(aliasedValue)); throw new AnnotationConfigurationException(msg); } } else if (aliasPresent) { // Replace value with aliasedValue attributes.put(attributeName, adaptValue(element, aliasedValue, classValuesAsString, nestedAnnotationsAsMap)); valuesAlreadyReplaced.add(attributeName); } else { // Replace aliasedValue with value attributes.put(aliasedAttributeName, adaptValue(element, value, classValuesAsString, nestedAnnotationsAsMap)); valuesAlreadyReplaced.add(aliasedAttributeName); } } } } //将注解属性方法的值是<SPRING DEFAULT VALUE PLACEHOLDER>替换成属性方法的默认值,如@Autowired的required的默认值是true for (String attributeName : attributes.keySet()) { if (valuesAlreadyReplaced.contains(attributeName)) { continue; } Object value = attributes.get(attributeName); if (value == DEFAULT_VALUE_PLACEHOLDER) { attributes.put(attributeName, adaptValue(element, getDefaultValue(annotationType, attributeName), classValuesAsString, nestedAnnotationsAsMap)); } } }
经过漫长枯燥的解析,我们终于得到了Car 的@Autowired注解的required属性的默认值是true 。经过上面的分析,我们得到了InjectionMetadata对象,下面,我们来继续分析属性的注入。
InjectionMetadata.java
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); } element.inject(target, beanName, pvs); } } }
AutowiredFieldElement.java
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { Field field = (Field) this.member; try { Object value; if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { //创建属性的描述器 DependencyDescriptor desc = new DependencyDescriptor(field, this.required); //设置属性的bean 的class desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<String>(1); //获取工厂bean的类型转换器 TypeConverter typeConverter = beanFactory.getTypeConverter(); //获取到属性的具体值,比如Car对象 value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); synchronized (this) { if (!this.cached) { if (value != null || this.required) { this.cachedFieldValue = desc; //注册bean之间的依赖关系,也就是User中有属性Car, Car 在User中使用过等,这样的信息 registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName)) { // 名称是否匹配 if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { // 创建bean的引用 this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName); } } } } else { this.cachedFieldValue = null; } this.cached = true; } } } if (value != null) { // 通过反射将属性值设置到bean中 ReflectionUtils.makeAccessible(field); field.set(bean, value); } } catch (Throwable ex) { throw new BeanCreationException("Could not autowire field: " + field, ex); } }
DefaultListableBeanFactory.java
public Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) { return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName); } else if (ObjectFactory.class == descriptor.getDependencyType()) { return new DependencyObjectFactory(descriptor, beanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName); } else { //如果属性是延迟初始化,做相应的处理 Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName); if (result == null) { //真正的解析bean result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter); } return result; } } public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { 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())); } if (type.isArray()) { Class<?> componentType = type.getComponentType(); DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor); } 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 Object[]) { Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans)); } return result; } else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getCollectionType(); if (elementType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]"); } return null; } DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor); } 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.isAssignableFrom(type) && type.isInterface()) { Class<?> keyType = descriptor.getMapKeyType(); if (String.class != keyType) { if (descriptor.isRequired()) { throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() + "] must be [java.lang.String]"); } return null; } Class<?> valueType = descriptor.getMapValueType(); if (valueType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No value type declared for map [" + type.getName() + "]"); } return null; } DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { //如果autowired的required为true,但是容器中并没有这个bean,则抛出异常 if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(type, "", descriptor); } return null; } //如果通过名称获取到多个bean对象 if (matchingBeans.size() > 1) { String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor); //如果没有设置@Primary注解,则直接抛出异常 if (primaryBeanName == null) { throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet()); } if (autowiredBeanNames != null) { //如果设置了@Primary,则取设置了@Primary的作为注入值 autowiredBeanNames.add(primaryBeanName); } return matchingBeans.get(primaryBeanName); } Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); if (autowiredBeanNames != null) { autowiredBeanNames.add(entry.getKey()); } //返回属性值 return entry.getValue(); } } protected Map<String, Object> findAutowireCandidates( String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length); for (Class<?> autowiringType : this.resolvableDependencies.keySet()) { if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = this.resolvableDependencies.get(autowiringType); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } for (String candidateName : candidateNames) { //不是自己引用自己,包括类对象是否引用了自己的工厂方法。 if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, descriptor)) { //到这里,我们终于看到了关键方法,通过getBean获取car的bean对象 result.put(candidateName, getBean(candidateName)); } } if (result.isEmpty()) { DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidateName : candidateNames) { if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, fallbackDescriptor)) { result.put(candidateName, getBean(candidateName)); } } } return result; }
到这里,我们己经得到了属性的具体值。我们再次回到属性注入方法,inject ,我们到这里,己经将属性的注入分析完了,我们还是来总结一下吧。
- 获取到注解的所有的属性。
- 查看注解中是否包含@Autowired注解或者@Value注解
- 如果有@Autowired注解,获取@Autowired注解的属性方法required的值
- 调用getBean()方法,获取属性对象
- 通过反射将属性值注入对象
到这里,己经将User 的Car 属性注入解析完成,Dog对象,也是相同的解析办法,这里将不再做过多的缀述了。
本文的 github 地址是
https://github.com/quyixiao/spring_tiny/tree/master/src/main/java/com/spring_1_100/test_31_40/test35_resource_inject