深度解读依赖注入DI源码

spring-framework-5.3.10 版本

依赖注入代码的入口在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 。如果想搞清楚为什么是这里需要去学习下Bean的生命周期,这里就不介绍了。

@Autowired

@Autowired
private OrderService orderService;

使用@Autowired注解,在程序执行时会调用populateBean方法中的postProcessProperties

深度解读依赖注入DI源码_第1张图片

最终会进入到org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties。首先会去查找注入点,注入点也就是需要进行自动注入的属性方法

深度解读依赖注入DI源码_第2张图片

findAutowiringMetadata 中会调用 buildAutowiringMetadata 这个就是寻找注入点最后核心的方法。

寻找注入点

先来看一下全貌,然后我们一起逐行进行分析。这段代码可以分成两大块14-30行用来寻找属性的注入点,33到60行用来寻找方法的注入点。

private InjectionMetadata buildAutowiringMetadata(final Class clazz) {
   // 如果一个Bean的类型是String...,那么则根本不需要进行依赖注入
   if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
      return InjectionMetadata.EMPTY;
   }

   List elements = new ArrayList<>();
   Class targetClass = clazz;

   do {
      final List currElements = new ArrayList<>();

      // 遍历targetClass中的所有Field
      ReflectionUtils.doWithLocalFields(targetClass, field -> {
         // field上是否存在@Autowired、@Value、@Inject中的其中一个
         MergedAnnotation ann = findAutowiredAnnotation(field);
         if (ann != null) {
            // static filed不是注入点,不会进行自动注入
            if (Modifier.isStatic(field.getModifiers())) {
               if (logger.isInfoEnabled()) {
                  logger.info("Autowired annotation is not supported on static fields: " + field);
               }
               return;
            }
            //获取@Autowired中的required属性的值
            boolean required = determineRequiredStatus(ann);
            // 构造注入点
            currElements.add(new AutowiredFieldElement(field, required));
         }
      });

      // 遍历targetClass中的所有Method
      ReflectionUtils.doWithLocalMethods(targetClass, method -> {

         Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
         if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
            return;
         }
         // method上是否存在@Autowired、@Value、@Inject中的其中一个
         MergedAnnotation ann = findAutowiredAnnotation(bridgedMethod);
         if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
            // static method不是注入点,不会进行自动注入
            if (Modifier.isStatic(method.getModifiers())) {
               if (logger.isInfoEnabled()) {
                  logger.info("Autowired annotation is not supported on static methods: " + method);
               }
               return;
            }
            // set方法最好有入参
            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);
}

3-5行 判断当前类是否不需要寻找注入点。底层判断逻辑代码如下

static boolean hasPlainJavaAnnotationsOnly(Class type) {
   return (type.getName().startsWith("java.") || type == Ordered.class);
}

寻找属性注入点

14-30行用来寻找属性的注入点

  1. 14行 ReflectionUtils.doWithLocalFields 会遍历当前类里面的所有字段。

  1. 16行 然后去findAutowiredAnnotation 判断当前字段上是否存在@Autowired、@Value、@Inject中的其中一个,如果存在任意一个则当前字段判断为注入点。

  1. 19行 如果属性是static的不进行注入,因为在原型模式下,static属性多个对象赋值时会存在覆盖。

  1. 26行 查看当前属性是否要求必须注入,required默认为true。

  1. 28行 将找到的注入点放入currElements,最终通过67行 InjectionMetadata.forElements 封装成InjectionMetadata对象。

寻找方法注入点

33到60行用来寻找方法的注入点。寻找方法注入点和属性注入点类似。主要说明以下几个地方

35-38行 这里判断是否为桥接方法,并对桥接方法进行过滤。 这里主要是处理泛型接口的实现类中的注入,了解即可。

50行 这里即使方法上没有入参,如果添加了@Autowired注解方法也会执行。

注意第10-65行,是一个do while,看第63行可以理解,逻辑时先找自己的注入点,然后去找父类。知道找到所有注入点。

67行 InjectionMetadata.forElements 将属性和方法上的注入点,封装成InjectionMetadata对象,并返回

进行依赖注入

寻找到注入点以后,接下来就是对注入点的属性和方法进行依赖注入了。metadata.inject(bean, beanName, pvs); 实现依赖注入

深度解读依赖注入DI源码_第3张图片

同样的注入也分为属性注入和方法注入

深度解读依赖注入DI源码_第4张图片

属性注入

@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

   Field field = (Field) this.member;
   Object value;
   if (this.cached) {
      // 对于原型Bean,第一次创建的时候,也找注入点,然后进行注入,此时cached为false,注入完了之后cached为true
      // 第二次创建的时候,先找注入点(此时会拿到缓存好的注入点),也就是AutowiredFieldElement对象,此时cache为true,也就进到此处了
      // 注入点内并没有缓存被注入的具体Bean对象,而是beanName,这样就能保证注入到不同的原型Bean对象
      try {
         value = resolvedCachedArgument(beanName, this.cachedFieldValue);
      }
      catch (NoSuchBeanDefinitionException ex) {
         // Unexpected removal of target bean for cached argument -> re-resolve
         value = resolveFieldValue(field, bean, beanName);
      }
   }
   else {
      // 根据filed从BeanFactory中查到的匹配的Bean对象
      value = resolveFieldValue(field, bean, beanName);
   }

   // 反射给filed赋值
   if (value != null) {
      ReflectionUtils.makeAccessible(field);
      field.set(bean, value);
   }
}

6-17行 先判断缓存里是否有,如果没有调用resolveFieldValue获取到属性值

24-26行 利用反射将属性值注入到属性

resolveFieldValue方法是注入的核心,我们进到这个方法里看看

@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {

   DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
   desc.setContainingClass(bean.getClass());

   Set autowiredBeanNames = new LinkedHashSet<>(1);
   Assert.state(beanFactory != null, "No BeanFactory available");
   TypeConverter typeConverter = beanFactory.getTypeConverter();
   Object value;
   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) {
         Object cachedFieldValue = null;
         if (value != null || this.required) {
            cachedFieldValue = desc;
            // 注册一下beanName依赖了autowiredBeanNames,
            registerDependentBeans(beanName, autowiredBeanNames);
            if (autowiredBeanNames.size() == 1) {
               String autowiredBeanName = autowiredBeanNames.iterator().next();
               if (beanFactory.containsBean(autowiredBeanName) &&
                     beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                  // 构造一个ShortcutDependencyDescriptor作为缓存,保存了当前filed所匹配的autowiredBeanName,而不是对应的bean对象(考虑原型bean)
                  cachedFieldValue = new ShortcutDependencyDescriptor(
                        desc, autowiredBeanName, field.getType());
               }
            }
         }
         this.cachedFieldValue = cachedFieldValue;
         this.cached = true;
      }
   }
   return value;
}

4行 生成依赖描述器

resolveDependency

12行 是一个核心方法resolveDependency。我们在进入这个方法来看看

@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
      @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
   // 用来获取方法入参名字的
   descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

   // 所需要的类型是Optional
   if (Optional.class == descriptor.getDependencyType()) {
      return createOptionalDependency(descriptor, requestingBeanName);
   }
   // 所需要的的类型是ObjectFactory,或ObjectProvider
   else if (ObjectFactory.class == descriptor.getDependencyType() ||
         ObjectProvider.class == descriptor.getDependencyType()) {
      return new DependencyObjectProvider(descriptor, requestingBeanName);
   }
   else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
      return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
   }
   else {
      // 在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
      Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
            descriptor, requestingBeanName);

      if (result == null) {
         // descriptor表示某个属性或某个set方法
         // requestingBeanName表示正在进行依赖注入的Bean
         result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
      }
      return result;
   }
}

6行 获取方法的入参名字

8-19行 处理一些特殊的情况。不做分析

22-28行 这里才是我们常用的情况

@Lazy注解

22行 判断属性上是否添加了@Lazy注解,或者方法参数前面是否添加了@Lazy注解。如果添加了@Lazy注解,说明属性不会在这里进行注入。而是等待真正使用的时候才进行注入,此时属性并没有真正注入,而是返回一个代理对象。在真正使用时通过代理对象进行依赖注入,并返回注入后的对象。

doResolveDependency方法

如果没有添加@Lazy注解,会进入到28行 doResolveDependency 这是依赖注入的重中之重。

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
      @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

   InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
   try {
      // 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
      Object shortcut = descriptor.resolveShortcut(this);
      if (shortcut != null) {
         return shortcut;
      }

      Class type = descriptor.getDependencyType();
      // 获取@Value所指定的值
      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);
            // 解析Spring表达式(#{})
            value = evaluateBeanDefinitionString(strVal, bd);
         }
         // 将value转化为descriptor所对应的类型
         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
         try {
            return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
         }
         catch (UnsupportedOperationException ex) {
            // A custom TypeConverter which does not support TypeDescriptor resolution...
            return (descriptor.getField() != null ?
                  converter.convertIfNecessary(value, type, descriptor.getField()) :
                  converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
         }
      }

      // 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了
      Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
      if (multipleBeans != null) {
         return multipleBeans;
      }

      // 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
      Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
      if (matchingBeans.isEmpty()) {
         // required为true,抛异常
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         return null;
      }

      String autowiredBeanName;
      Object instanceCandidate;

      if (matchingBeans.size() > 1) {
         // 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
         autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
         if (autowiredBeanName == null) {
            if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
               return descriptor.resolveNotUnique(descriptor.getResolvableType(), 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 entry = matchingBeans.entrySet().iterator().next();
         autowiredBeanName = entry.getKey();
         instanceCandidate = entry.getValue();
      }

      // 记录匹配过的beanName
      if (autowiredBeanNames != null) {
         autowiredBeanNames.add(autowiredBeanName);
      }
      // 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
      if (instanceCandidate instanceof Class) {
         instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
      }
      Object result = instanceCandidate;
      // 处理只有名字没有对象的特殊情况
      if (result instanceof NullBean) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         result = null;
      }
      if (!ClassUtils.isAssignableValue(type, result)) {
         throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
      }
      return result;
   }
   finally {
      ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
   }
}

@Value解析

15-36行 是对@Value注解的解析

19行 占位符填充(${}) 从properties文件中或者运行时使用-D指定的环境变量中。以占位符作为key,读取值填充到属性中。

@Value("${user.name}")
private String name;

使用properties时需要引入

@PropertySource("classpath:spring.properties")
public class AppConfig {

23行 解析Spring表达式(#{}) 从spring容器中找到符合的bean

@Value("#{orderServie}") 
private OrderService orderService;

25-35行 是一个类型转化器,可以对@Value解析出来的值利用转化器转成目标属性的类型

38-42行 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了。例如

@Autowired
private Map orderServiceMap;

45行findAutowireCandidates根据传入的类型和beanName找到所需的Bean,Map 找到符合的Bean可能不止一个,这里String对应Bean的名字,Object对应的并不是Bean本身,而是Bean的Class,这样设计是因为我们找到了多个Bean以后,只需要对匹配的Bean进行实例化就可以了,多余的bean不需要处理。所以只取了class,没有取实例化以后的bean。

// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
 Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);

46-51行 如果没有找到bean,并且isRequired为true则抛异常,如果isRequired为false则返回null

      if (matchingBeans.isEmpty()) {
         // required为true,抛异常
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         return null;
      }

57-72行 如果找到了多个Bean,需要调用determineAutowireCandidate方法进行过滤,找到符合条件的唯一Bean

@Primary @Priority

determineAutowireCandidate中会根据 @Primary-->@Priority优先级最高--->name 的顺序取Bean。 @Priority只能写在类上。

如果获取不到判断是否isRequired为ture,逻辑和上面一样。

if (matchingBeans.size() > 1) {
         // 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
         autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
         if (autowiredBeanName == null) {
            if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
               return descriptor.resolveNotUnique(descriptor.getResolvableType(), 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);
      }

73-78行 如果只找到了唯一的bean,那么这个bean就是我们想要的了。

else {
         // We have exactly one match.
         Map.Entry entry = matchingBeans.entrySet().iterator().next();
         autowiredBeanName = entry.getKey();
         instanceCandidate = entry.getValue();
      }

85-87行 后面的逻辑就是将筛选出来的bean对应的class进行实例化,然后将实例化以后的bean返回给属性进行注入

 // 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
      if (instanceCandidate instanceof Class) {
         instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
      }

90-95行 处理只有名字,bean为null的特殊情况。

if (result instanceof NullBean) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         result = null;
      }

findAutowireCandidates

我们在回头看下45行findAutowireCandidates

protected Map findAutowireCandidates(
      @Nullable String beanName, Class requiredType, DependencyDescriptor descriptor) {

   // 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化
   String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
         this, requiredType, true, descriptor.isEager());
   Map result = CollectionUtils.newLinkedHashMap(candidateNames.length);

   // 根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置
   for (Map.Entry, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
      Class autowiringType = classObjectEntry.getKey();
      if (autowiringType.isAssignableFrom(requiredType)) {
         Object autowiringValue = classObjectEntry.getValue();
         autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);

         if (requiredType.isInstance(autowiringValue)) {
            result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
            break;
         }
      }
   }


   for (String candidate : candidateNames) {
      // 如果不是自己,则判断该candidate到底能不能用来进行自动注入
      if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
         addCandidateEntry(result, candidate, descriptor, requiredType);
      }
   }

   // 为空要么是真的没有匹配的,要么是匹配的自己
   if (result.isEmpty()) {
      // 需要匹配的类型是不是Map、数组之类的
      boolean multiple = 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) &&
               (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
            addCandidateEntry(result, candidate, descriptor, requiredType);
         }
      }

      // 匹配的是自己,被自己添加到result中
      if (result.isEmpty() && !multiple) {
         // 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;
}

5行 从spring容器中,通过单例池和BeanDefinitionMap中找到符合的Bean

10-21行 遍历 , Object> resolvableDependencies 中记录了一个Class对应的Bean对象是什么

24-28行 candidateNames中存储了符合条件的bean的名字。 如果是自己注入自己,例如下面这种,如果还存在另外一个UserService类型,优先使用非自己的bean进行注入。

public class UserService {

   @Autowired
   UserService userService;

isAutowireCandidate用来判断一个bean是否可以进行依赖注入。这里用到了责任链

org.springframework.beans.factory.support.SimpleAutowireCandidateResolver#isAutowireCandidate

org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate 处理泛型

org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate 处理Qualifier

@Bean(autowireCandidate = false)
public UserService userService() {
   return new UserService();
}

32-56行 判断是否存在符合条件的bean,如果没有找到符合条件的bean.在看看自己是否是符合条件的。因为在24-28行中排出了自己。

方法注入

@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
   // 如果pvs中已经有当前注入点的值了,则跳过注入
   if (checkPropertySkipping(pvs)) {
      return;
   }
   Method method = (Method) this.member;
   Object[] arguments;
   if (this.cached) {
      try {
         arguments = resolveCachedArguments(beanName);
      }
      catch (NoSuchBeanDefinitionException ex) {
         // Unexpected removal of target bean for cached argument -> re-resolve
         arguments = resolveMethodArguments(method, bean, beanName);
      }
   }
   else {
      arguments = resolveMethodArguments(method, bean, beanName);
   }
   if (arguments != null) {
      try {
         ReflectionUtils.makeAccessible(method);
         method.invoke(bean, arguments);
      }
      catch (InvocationTargetException ex) {
         throw ex.getTargetException();
      }
   }
}

方法注入和属性注入类似,只是方法的入参可能是多个,所以会遍历每一个参数去获取参数值,然后注入。

resolveMethodArguments方法中同样会调用resolveDependency。这里的逻辑就和上面一样了。

Autowire.BY_NAME

找出对象中所有的set方法,然后将setXXX后面的XXX作为属性名称,在容器中取得Bean进行注入。

@ComponentScan("com.mtb")
public class AppConfig {
   @Bean(autowire = Autowire.BY_NAME)
   public UserService userService() {
      return new UserService();
   }
}
@Component
public class UserService {

   private OrderService orderService;

   public void test() {
      System.out.println(orderService);
   }

   public void setOrderService(OrderService orderService) {
      this.orderService = orderService;
   }
}

使用这种方式会进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByName

深度解读依赖注入DI源码_第5张图片

进入autowireByName后,会通过unsatisfiedNonSimpleProperties拿到bean中需要注入的所有属性名字

深度解读依赖注入DI源码_第6张图片

进入以后,先获取属性描述器

深度解读依赖注入DI源码_第7张图片

PropertyDescriptor中有几个属性:

name:这个name并不是方法的名字,而是拿方法名字进过处理后的名字
如果方法名字以“get”开头,比如“getXXX”,那么name=XXX
如果方法名字以“is”开头,比如“isXXX”,那么name=XXX
如果方法名字以“set”开头,比如“setXXX”,那么name=XXX
readMethodRef:表示get方法的Method对象的引用
readMethodName:表示get方法的名字
writeMethodRef:表示set方法的Method对象的引用
writeMethodName:表示set方法的名字
propertyTypeRef:如果有get方法那么对应的就是返回值的类型,如果是set方法那么对应的就是set方法中唯一参数的类型

这里需要注意getPropertyDescriptors获取的不是对象中的属性,而是对象中的set方法,然后将set方法后面内容作为属性名。例如userService中的setOrderService,会把set后面的orderSercie作为属性名字。所以使用byName时,必须要有对应的set方法。

通过debug我们可以看到pds中解析出来了orderService属性

深度解读依赖注入DI源码_第8张图片

pvs.contains(pd.getName()) 如果在依赖注入前,已经注入了值(例如程序员使用了beanDefinition设置了值),那么不在自动注入。

BeanUtils.isSimpleProperty(pd.getPropertyType()) 如果是简单类型也不注入

深度解读依赖注入DI源码_第9张图片

简单类型如下:

public static boolean isSimpleValueType(Class type) {
   return (Void.class != type && void.class != type &&
         (ClassUtils.isPrimitiveOrWrapper(type) ||
         Enum.class.isAssignableFrom(type) ||
         CharSequence.class.isAssignableFrom(type) ||
         Number.class.isAssignableFrom(type) ||
         Date.class.isAssignableFrom(type) ||
         Temporal.class.isAssignableFrom(type) ||
         URI.class == type ||
         URL.class == type ||
         Locale.class == type ||
         Class.class == type));
}

执行完unsatisfiedNonSimpleProperties方法后,获取到了所有需要注入的属性。然后通过getBean获取bean,加入到pvs中。

深度解读依赖注入DI源码_第10张图片

最终会在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 方法中调用applyPropertyValues 完成注入

深度解读依赖注入DI源码_第11张图片

Autowire.BY_TYPE

Autowire.BY_TYPE的流程与BY_NAME相似。 byType或通过入参去查找对象。

@Resource

寻找注入点

@resource注解通过org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#findResourceMetadata查找注入点 ,调用buildResourceMetadata查找添加了@Resouce注解的属性或方法。 如果属性是static的会报错。

深度解读依赖注入DI源码_第12张图片

进行依赖注入

流程和@Autowired类似,核心调用方法如下

org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.ResourceElement#ResourceElement

public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
   super(member, pd);
   Resource resource = ae.getAnnotation(Resource.class);
   String resourceName = resource.name();
   Class resourceType = resource.type();

   // 使用@Resource时没有指定具体的name,那么则用field的name,或setXxx()中的xxx
   this.isDefaultName = !StringUtils.hasLength(resourceName);
   if (this.isDefaultName) {
      resourceName = this.member.getName();
      if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
         resourceName = Introspector.decapitalize(resourceName.substring(3));
      }
   }
   // 使用@Resource时指定了具体的name,进行占位符填充
   else if (embeddedValueResolver != null) {
      resourceName = embeddedValueResolver.resolveStringValue(resourceName);
   }

   // @Resource除开可以指定bean,还可以指定type,type默认为Object
   if (Object.class != resourceType) {
      // 如果指定了type,则验证一下和field的类型或set方法的第一个参数类型,是否和所指定的resourceType匹配
      checkResourceType(resourceType);
   }
   else {
      // No resource type specified... check field/method.
      resourceType = getResourceType();
   }
   this.name = (resourceName != null ? resourceName : "");
   this.lookupType = resourceType;

   String lookupValue = resource.lookup();
   this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());

   Lazy lazy = ae.getAnnotation(Lazy.class);
   this.lazyLookup = (lazy != null && lazy.value());
}

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#autowireResource

protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
      throws NoSuchBeanDefinitionException {

   Object resource;
   Set autowiredBeanNames;
   String name = element.name;

   if (factory instanceof AutowireCapableBeanFactory) {
      AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
      DependencyDescriptor descriptor = element.getDependencyDescriptor();

      // 假设@Resource中没有指定name,并且field的name或setXxx()的xxx不存在对应的bean,那么则根据field类型或方法参数类型从BeanFactory去找
      if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
         autowiredBeanNames = new LinkedHashSet<>();
         resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
         if (resource == null) {
            throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
         }
      }
      else {
         resource = beanFactory.resolveBeanByName(name, descriptor);
         autowiredBeanNames = Collections.singleton(name);
      }
   }
   else {
      resource = factory.getBean(name, element.lookupType);
      autowiredBeanNames = Collections.singleton(name);
   }

   if (factory instanceof ConfigurableBeanFactory) {
      ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
      for (String autowiredBeanName : autowiredBeanNames) {
         if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
            beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
         }
      }
   }

   return resource;
}

@Resource和@Autowired的区别

@Resource 先byName再byType , @Autowired 先byType 再byName

@Resource 是jdk的注解,@Autowired 是spring的注解

你可能感兴趣的:(Spring,Spring,依赖注入DI,Autowired注解,Resouce注解,ByName,ByType)