SpringIOC-依赖注入实现
AutowiredAnnotationBeanPostProcessor类
AutowiredAnnotationBeanPostProcessor继承了InstantiationAwareBeanPostProcessor,这两个注解是由这个父类完成解析的,在AutowiredAnnotationBeanPostProcessor构造函数中在autowiredAnnotationTypes集合中添加了@Autowired,@Value的注解,主要是对@Autowired,@Value注解的支持。
determineCandidateConstructors
从缓存中获取构造函数数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { 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<>(rawCandidates.length); Constructor<?> requiredConstructor = null; Constructor<?> defaultConstructor = null; Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass); int nonSyntheticConstructors = 0; for (Constructor<?> candidate : rawCandidates) { if (!candidate.isSynthetic()) { nonSyntheticConstructors++; } else if (primaryConstructor != null) { continue; } MergedAnnotation<?> ann = findAutowiredAnnotation(candidate); if (ann == null) { Class<?> userClass = ClassUtils.getUserClass(beanClass); if (userClass != beanClass) { try { Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes()); ann = findAutowiredAnnotation(superCtor); } catch (NoSuchMethodException ex) { } } } if (ann != null) { if (requiredConstructor != null) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor); } 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.getParameterCount() == 0) { defaultConstructor = candidate; } } if (!candidates.isEmpty()) { if (requiredConstructor == null) { if (defaultConstructor != null) { candidates.add(defaultConstructor); } else if (candidates.size() == 1 && logger.isInfoEnabled()) { logger.info("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<?>[0]); } else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) { candidateConstructors = new Constructor<?>[]{rawCandidates[0]}; } else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) { candidateConstructors = new Constructor<?>[]{primaryConstructor, defaultConstructor}; } else if (nonSyntheticConstructors == 1 && primaryConstructor != null) { candidateConstructors = new Constructor<?>[]{primaryConstructor}; } else { candidateConstructors = new Constructor<?>[0]; } this.candidateConstructorsCache.put(beanClass, candidateConstructors); } } }
return (candidateConstructors.length > 0 ? candidateConstructors : null); }
|
关于 8.1 和 8.3 的异常校验,说的简单点:在一个 bean 中,只要有构造函数使用了 “@Autowired(required = true)” 或 “@Autowired”,就不允许有其他的构造函数使用 “@Autowire”;但是允许有多个构造函数同时使用 “@Autowired(required = false)”。
findAutowiredAnnotation
查找Autowired的注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
@Nullable private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) { MergedAnnotations annotations = MergedAnnotations.from(ao); for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) { MergedAnnotation<?> annotation = annotations.get(type); if (annotation.isPresent()) { return annotation; } } return null; }
|
postProcessMergedBeanDefinition
postProcessMergedBeanDefinition 被定义在 MergedBeanDefinitionPostProcessor 接口中,该方法的主要作用是:对指定 bean 的给定 MergedBeanDefinition 进行后置处理。
在 AutowiredAnnotationBeanPostProcessor 的实现中,主要是对使用了 @Autowire 注解的方法和属性进行预解析,并放到 injectionMetadataCache 缓存中,用于后续使用。
1 2 3 4 5 6 7 8 9 10 11 12
|
@Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); }
|
搜集方法以及字段的@Autowired注解并封装成InjectionMetadata
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable 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); } metadata = buildAutowiringMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; }
|
injectionMetadataCache是一个Map对象,缓存beanName与InjectionMetadata。InjectionMetadata对象通过buildAutowiringMetadata()方法来创建的。
搜集方法以及字段的@Autowired注解并封装成InjectionMetadata
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) { return InjectionMetadata.EMPTY; }
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>(); Class<?> targetClass = clazz; do { final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>(); ReflectionUtils.doWithLocalFields(targetClass, field -> { MergedAnnotation<?> ann = findAutowiredAnnotation(field); if (ann != null) { if (Modifier.isStatic(field.getModifiers())) { if (logger.isInfoEnabled()) { logger.info("Autowired annotation is not supported on static fields: " + field); } return; } boolean required = determineRequiredStatus(ann); currElements.add(new AutowiredFieldElement(field, required)); } }); ReflectionUtils.doWithLocalMethods(targetClass, method -> { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod); if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { if (Modifier.isStatic(method.getModifiers())) { if (logger.isInfoEnabled()) { logger.info("Autowired annotation is not supported on static methods: " + method); } return; } if (method.getParameterCount() == 0) { if (logger.isInfoEnabled()) { logger.info("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); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return InjectionMetadata.forElements(elements, clazz); }
|
buildAutowiringMetadata()方法分为对字段与方法的@Autowired(@Value,@Inject)注解处理。将标记@Autowired的费静态字段封装为AutowiredFieldElement对象,将标记@Autowired的非静态方法封装到AutowiredMethodElement对象然后都加入到InjectionMetadata中,此过程是一个循环过程此类处理完会沿着父类继续向上处理。AutowiredFieldElement与AutowiredMethodElement都是InjectionMetadata.InjectedElement的子类,都覆盖了父类的inject()方法这个下面会介绍。
通过findAutowiringMetadata()方法得到了InjectionMetadata对象之后调用了给对象的checkConfigMembers()方法。这个方法就是将上面保存的InjectedElement对象筛选出那些不存在于beanDefinition中的赋值给checkedElements。
checkConfigMembers
检测ConfigMembers并将InjectedElement集合赋值给全局的checkedElements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
public void checkConfigMembers(RootBeanDefinition beanDefinition) { Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size()); for (InjectedElement element : this.injectedElements) { Member member = element.getMember(); if (!beanDefinition.isExternallyManagedConfigMember(member)) { beanDefinition.registerExternallyManagedConfigMember(member); checkedElements.add(element); if (logger.isTraceEnabled()) { logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element); } } } this.checkedElements = checkedElements; }
|
到这为止就是postProcessMergedBeanDefinition()方法的全部实现逻辑并没有做什么实际事情,其实是为了后面的行为做铺垫,请看postProcessPropertyValues()方法,此方法是在属性填充阶段被调用的。
postProcessPropertyValues
postProcessPropertyValues 被定义在 InstantiationAwareBeanPostProcessor 接口中,该方法的主要作用是:将属性值应用于给定 bean 之前对给定属性值进行后置处理。
在 AutowiredAnnotationBeanPostProcessor 的实现中,主要是对使用了 @Autowire 注解的方法和属性进行自动注入,将依赖的 bean 赋值给对应的属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { 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; }
|
首先调用 findAutowiringMetadata()方法从缓存中再次取到InjectionMetadata对象,调用inject()方法完成autowired注入。
进行依赖注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Collection<InjectedElement> checkedElements = this.checkedElements; Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements); if (!elementsToIterate.isEmpty()) { for (InjectedElement element : elementsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean '" + beanName + "': " + element); } element.inject(target, beanName, pvs); } } }
|
因为之前已经把类@Autowired注解标记的字段或方法封装到了响应的InjectedElement子类中了,此时依次调用子类的inject()方法完成对象的注入,下面分别看一看这两种注入的实现。
依赖注入
解析 @Autowired 注解生成的元数据类:AutowiredFieldElement、AutowiredMethodElement,这两个类继承InjectionMetadata.InjectedElement,各自重写了 inject 方法。对于属性注入来说,会走到 AutowiredFieldElement 中的 inject 方法
AutowiredFieldElement#inject
属性的依赖注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
@Override protected void inject(Object bean, @Nullable String beanName, @Nullable 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<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); try { 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; registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName) && 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); } }
|
解析当前属性所匹配的 bean 实例,并把解析到的 bean 实例的 beanName 存储在 autowiredBeanNames 中
registerDependentBeans
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
private void registerDependentBeans(@Nullable String beanName, Set<String> autowiredBeanNames) { if (beanName != null) { for (String autowiredBeanName : autowiredBeanNames) { if (this.beanFactory != null && this.beanFactory.containsBean(autowiredBeanName)) { this.beanFactory.registerDependentBean(autowiredBeanName, beanName); } if (logger.isTraceEnabled()) { logger.trace("Autowiring by type from bean name '" + beanName + "' to bean named '" + autowiredBeanName + "'"); } } } }
|
如果 autowiredBeanName 在 BeanFactory 中存在,则注册依赖关系到缓存(beanName 依赖 autowiredBeanName
AutowiredMethodElement#inject
方法的依赖注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
@Override protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { if (checkPropertySkipping(pvs)) { return; } Method method = (Method) this.member; Object[] arguments; if (this.cached) { arguments = resolveCachedArguments(beanName); } else { int argumentCount = method.getParameterCount(); arguments = new Object[argumentCount]; DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount]; Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount); Assert.state(beanFactory != null, "No BeanFactory available"); 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 { Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter); 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) { DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length); registerDependentBeans(beanName, autowiredBeans); if (autowiredBeans.size() == argumentCount) { Iterator<String> it = autowiredBeans.iterator(); Class<?>[] paramTypes = method.getParameterTypes(); for (int i = 0; i < paramTypes.length; i++) { String autowiredBeanName = it.next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { cachedMethodArguments[i] = new ShortcutDependencyDescriptor( descriptors[i], autowiredBeanName, paramTypes[i]); } } } this.cachedMethodArguments = cachedMethodArguments; } else { this.cachedMethodArguments = null; } this.cached = true; } } } if (arguments != null) { try { ReflectionUtils.makeAccessible(method); method.invoke(bean, arguments); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } }
|