示例

平时我们在使用spring时,会使用autowired注入需要的对象实例,例如下面代码:在F类中注入I类的实例对象

  1. @Component
  2. public class F {
  3. @Autowired
  4. private I a;
  5. }
  1. public interface I {
  2. }
  1. @Component("a")
  2. public class IA implements I{
  3. }

注入原理分析

在使用Autowired属性注入时,其逻辑的主要是由AutowiredAnnotationBeanPostProcessor.AutowiredFieldElementresolveFieldValue进行实现
Autowired.jpg

核心代码

  1. public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
  2. @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
  3. InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
  4. try {
  5. Object shortcut = descriptor.resolveShortcut(this);
  6. if (shortcut != null) {
  7. return shortcut;
  8. }
  9. Class<?> type = descriptor.getDependencyType();
  10. Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
  11. if (value != null) {
  12. if (value instanceof String) {
  13. String strVal = resolveEmbeddedValue((String) value);
  14. BeanDefinition bd = (beanName != null && containsBean(beanName) ?
  15. getMergedBeanDefinition(beanName) : null);
  16. value = evaluateBeanDefinitionString(strVal, bd);
  17. }
  18. TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
  19. try {
  20. return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
  21. }
  22. catch (UnsupportedOperationException ex) {
  23. // A custom TypeConverter which does not support TypeDescriptor resolution...
  24. return (descriptor.getField() != null ?
  25. converter.convertIfNecessary(value, type, descriptor.getField()) :
  26. converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
  27. }
  28. }
  29. // 是否支持多个注入,则在该方法内部完成bean的查找,例如:list
  30. Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
  31. if (multipleBeans != null) {
  32. return multipleBeans;
  33. }
  34. // 完成查找,可能查找出多个结果
  35. Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
  36. if (matchingBeans.isEmpty()) {
  37. if (isRequired(descriptor)) {
  38. raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
  39. }
  40. return null;
  41. }
  42. String autowiredBeanName;
  43. Object instanceCandidate;
  44. if (matchingBeans.size() > 1) {
  45. // 决定使用哪个bean的name,后续实例化的时候需要使用到这个beanName
  46. autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
  47. if (autowiredBeanName == null) {
  48. if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
  49. return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
  50. }
  51. else {
  52. // In case of an optional Collection/Map, silently ignore a non-unique case:
  53. // possibly it was meant to be an empty collection of multiple regular beans
  54. // (before 4.3 in particular when we didn't even look for collection beans).
  55. return null;
  56. }
  57. }
  58. instanceCandidate = matchingBeans.get(autowiredBeanName);
  59. }
  60. else {
  61. // We have exactly one match.
  62. Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
  63. autowiredBeanName = entry.getKey();
  64. instanceCandidate = entry.getValue();
  65. }
  66. if (autowiredBeanNames != null) {
  67. autowiredBeanNames.add(autowiredBeanName);
  68. }
  69. if (instanceCandidate instanceof Class) {
  70. instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
  71. }
  72. Object result = instanceCandidate;
  73. if (result instanceof NullBean) {
  74. if (isRequired(descriptor)) {
  75. raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
  76. }
  77. result = null;
  78. }
  79. if (!ClassUtils.isAssignableValue(type, result)) {
  80. throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
  81. }
  82. return result;
  83. }
  84. finally {
  85. ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
  86. }
  87. }

注入原理

Spring源码-Autowired注入原理.drawio.png