• Spring中@Autowired注解的工作原理


    目录

    一、概述

    二、@Autowired注解的用法

    三、@Autowired自动装配原理

    四、源码调试环境

    五、AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()源码

    六、AutowiredAnnotationBeanPostProcessor#postProcessProperties()源码

    七、总结


    一、概述

    @Autowired注解大家再熟悉不过了,在项目中使用 @Autowired注解的比例非常高,可以说基本用过 Spring 的同学都接触过这个注解,因此,我们有必要详细了解一下其工作原理。

    @Autowired注解的作用是帮我们注入我们需要的对象,Spring会自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。

    在分析这个注解的实现原理之前,我们不妨先来回顾一下@Autowired注解的用法。

    二、@Autowired注解的用法

    先定义几个接口:

    @Repository
    public class UserDao {
    
    	public void insert() {
    		// 执行数据库操作
    	}
    
    }
    
    public interface UserService {
    
    	void insert();
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    @Autowired注解的主要使用方式有下面四种:

    • (一)、@Autowired注解应用于构造函数

      @Service
      public class UserServiceImpl implements UserService {

      private final UserDao userDao;
      
      @Autowired
      public UserServiceImpl(UserDao userDao) {
      	this.userDao = userDao;
      }
      
      @Override
      public void insert() {
      	userDao.insert();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      }

    • (二)、@Autowired注释应用于setter方法

      @Service
      public class UserServiceImpl implements UserService {

      private UserDao userDao;
      
      @Autowired
      public void setUserDao(UserDao userDao) {
      	this.userDao = userDao;
      }
      
      @Override
      public void insert() {
      	userDao.insert();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      }

    • (三)、@Autowired应用于字段

      @Service
      public class UserServiceImpl implements UserService {

      @Autowired
      private UserDao userDao;
      
      @Override
      public void insert() {
      	userDao.insert();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      }

    • (四)、@Autowired应用于类型数组/集合对象的字段或方法

      public interface ICalculateStrategy {
      void calculate();
      }

      @Component
      public class StategyA implements ICalculateStrategy {
      @Override
      public void calculate() {

      }
      
      • 1

      }

      @Component
      public class StategyB implements ICalculateStrategy {
      @Override
      public void calculate() {

      }
      
      • 1

      }

      @Service
      public class UserServiceImpl implements UserService {

      @Autowired
      private ICalculateStrategy[] calculateStrategies;
      
      @Autowired
      private List calculateStrategyList;
      
      @Override
      public void insert() {
      	//[com.wsh.autowired.StategyA@490d6c15, com.wsh.autowired.StategyB@7d4793a8]
      	System.out.println(Arrays.toString(calculateStrategies));
      	//[com.wsh.autowired.StategyA@490d6c15, com.wsh.autowired.StategyB@7d4793a8]
      	System.out.println(calculateStrategyList);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      }

      @Configuration
      @ComponentScan(“com.wsh.autowired”)
      public class AppConfig {

      }

      public class Client {
      public static void main(String[] args) {
      AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
      UserService userService = (UserService) annotationConfigApplicationContext.getBean(“userServiceImpl”);
      userService.insert();
      }
      }

    三、@Autowired自动装配原理

    首先看一下@Autowired这个注解在Spring中的定义:

    // 可作用于: 构造方法、普通方法、参数、字段、注解上
    @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
    // 保留策略是运行时
    @Retention(RetentionPolicy.RUNTIME)
    // @Documented: 表明是否在java doc中添加Annotation
    @Documented
    public @interface Autowired {
    
    	/**
    	 * 声明这个依赖是否必须,默认为true
    	 */
    	boolean required() default true;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    我们可以看到,@Autowired注解可以应用在构造方法,普通方法,参数,字段,以及注解这五种类型的地方,它的保留策略是在运行时。在Spring中,@Autowired注解位于org.springframework.beans.factory.annotation包下面,我们发现在这个包下面还有一个关键的类:AutowiredAnnotationBeanPostProcessor。

    看名字盲猜AutowiredAnnotationBeanPostProcessor可能与@Autowired自动注入功能有关,确实,Spring对@Autowired注解的实现逻辑就在AutowiredAnnotationBeanPostProcessor实现的。

    先看一下AutowiredAnnotationBeanPostProcessor类的继承关系图:

    可以看到,AutowiredAnnotationBeanPostProcessor间接实现了InstantiationAwareBeanPostProcessor和

    MergedBeanDefinitionPostProcessor两个BeanPostProcessor后置处理器接口,通过之前的文章,大家对BeanPostProcessor应该不陌生了,Spring很多功能都是利用BeanPostProcessor后置处理器来实现的。

    • MergedBeanDefinitionPostProcessor类:合并Bean的定义信息

      // 合并Bean的定义信息的后处理方法,该方法是在Bean的实例化之后设置值之前调用。
      void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName);

    MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法的调用时机是在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors方法,而applyMergedBeanDefinitionPostProcessors()方法是在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean通过反射创建bean的实例之后调用的。

    • InstantiationAwareBeanPostProcessor类:在 Bean 实例化前后和Bean设置属性值时执行的后置处理器

      default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
      throws BeansException {

      return null;
      
      • 1

      }

    在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean()给bean的属性赋值方法中,会执行InstantiationAwareBeanPostProcessor的postProcessProperties()方法回调,如下图:

    postProcessProperties()方法的作用: 允许对填充前的属性进行处理(如对属性的验证)

    回顾一下Spring的创建流程:doCreateBean()通过反射创建bean的实例 -> applyMergedBeanDefinitionPostProcessors()执行MergedBeanDefinitionPostProcessor后置处理器增强方法postProcessMergedBeanDefinition() -> populateBean()属性填充 -> 执行InstantiationAwareBeanPostProcessor的postProcessProperties()方法回调 -> 初始化bean。

    可以看到,在实例化bean之后,就会调用AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法,然后在属性填充的时候,会调用AutowiredAnnotationBeanPostProcessor#postProcessProperties方法,我们按照这个先后顺序进行分析。

    所以,我们将重点关注在AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法以及AutowiredAnnotationBeanPostProcessor#postProcessProperties方法即可,下面挨个进行分析。

    四、源码调试环境

    下面以一个示例来跟踪@Autowired的整体执行流程。代码比较简单,这里就不过多说明,如下所示:

    @Repository
    public class UserDao {
    
    	public void insert() {
    		// 执行数据库操作
    	}
    
    }
    
    public interface UserService {
    
    	void insert();
    
    }
    
    @Service
    public class UserServiceImpl implements UserService {
    
    	@Autowired
    	private UserDao userDao;
    
    	@Override
    	public void insert() {
    	}
    
    }
    
    @Configuration
    @ComponentScan("com.wsh.autowired")
    public class AppConfig {
    
    }
    
    public class Client {
    	public static void main(String[] args) {
    		AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
    		UserService userService = (UserService) annotationConfigApplicationContext.getBean("userServiceImpl");
    		userService.insert();
    	}
    }
    
    • 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

    Spring 是如何实现自动装配的呢? 我们慢慢往下看(注意:主要以 @Autowired 为例来讲解)

    五、AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()源码

    AutowiredAnnotationBeanPostProcessor后置处理器主要负责对添加了@Autowired和@Value注解的元素实现自动装配。所以找到需要自动装配的元素,其实就是对@Autowired和@Value注解的解析,找出需要自动装配的元素是在MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法中实现的,而AutowiredAnnotationBeanPostProcessor间接实现了MergedBeanDefinitionPostProcessor,所以我们从AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法开始分析。

    我们以Debug方式启动Client,当我们执行new AnnotationConfigApplicationContext(AppConfig.class)时,会执行Spring IOC容器的初始化,熟悉IOC的小伙伴都知道,在刷新容器方法refresh()中有一个非常关键的步骤:finishBeanFactoryInitialization(beanFactory),那就是实例化所有剩下的非懒加载的单例Bean。

    本例中我们主要分析userServiceImpl这个bean的实例化过程。

    执行getBean(“userServiceImpl”) -> doCreateBean(“userServiceImpl”),在doCreateBean()方法中,有一个方法:applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);它会执行MergedBeanDefinitionPostProcessor后置处理器增强方法postProcessMergedBeanDefinition(),允许修改 MergedBeanDefinition。

    由于AutowiredAnnotationBeanPostProcessor间接实现了MergedBeanDefinitionPostProcessor,所以会执行到

    AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法,如下图。

    接着我们看下AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法的源码:

    // org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    postProcessMergedBeanDefinition()方法主要逻辑是在findAutowiringMetadata()方法。这个方法主要是找到需要自动装配的元素,该方法会去调用buildAutowiringMetadata()方法构建元数据信息。

    private InjectionMetadata findAutowiringMetadata(String beanName, Class clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        // 缓存key, 在本例中就是bean的名称:userServiceImpl
        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);
                    }
                    // 获取目标类对应的自动注入相关的元数据信息
                    metadata = buildAutowiringMetadata(clazz);
                    // 存入缓存
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    核心逻辑在buildAutowiringMetadata()方法,源码如下:

    private InjectionMetadata buildAutowiringMetadata(final Class clazz) {
        List elements = new ArrayList<>();
        Class targetClass = clazz;
    
        do {
            // 存放找到的元数据信息
            final List currElements = new ArrayList<>();
    
            // 通过反射获取目标类中所有的字段,并遍历每一个字段,然后通过findAutowiredAnnotation()方法判断字段是否使用@Autowired和@Value修饰,
            // 如果字段被@Autowired和@Value修饰,则返回注解的相关属性信息
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                // findAutowiredAnnotation(): 判断字段是否使用@Autowired和@Value修饰,并返回相关属性
                AnnotationAttributes ann = findAutowiredAnnotation(field);
                if (ann != null) {
                    // 校验@Autowired和@Value修饰注解是否应用在static方法上
                    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);
                    // 将该字段封成AutowiredFieldElement对象
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            });
    
            // 前面是通过反射获取目标类中所有的字段,这里是通过反射获取目标类中所有的方法
            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                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.isInfoEnabled()) {
                            logger.info("Autowired annotation is not supported on static methods: " + method);
                        }
                        return;
                    }
                    // 判断方法的参数个数是否为0
                    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);
                    // 将该字段封成AutowiredMethodElement对象
                    currElements.add(new AutowiredMethodElement(method, required, pd));
                }
            });
    
            elements.addAll(0, currElements);
            targetClass = targetClass.getSuperclass();
        }
        // 循环处理父类需要自动装配的元素
        while (targetClass != null && targetClass != Object.class);
        // 将目标类对应的所有自动注入相关的元信息封装成InjectionMetadata,然后合并到Bean定义中
        // 包含所有带有@Autowired注解修饰的一个InjectionMetadata集合. 由两部分组成: 一是我们处理的目标类,二就是上述方法获取到的所以elements集合。
        return new InjectionMetadata(clazz, elements);
    }
    
    • 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

    buildAutowiringMetadata()方法的处理流程:

    • (1)、通过反射获取目标类中所有的字段,并遍历每一个字段,然后通过findAutowiredAnnotation()方法判断字段是否使用@Autowired和@Value修饰,如果字段被@Autowired和@Value修饰,则返回注解的相关属性信息;

    在本例中,目标类是com.wsh.autowired.UserServiceImpl,此时目标类中有一个字段userDao,如下图:

    然后通过findAutowiredAnnotation(field)方法查找此属性是否被@Autowired注解修饰,很显然,我们的userDao使用了@Autowired注解修饰,所以能够获取到注解的属性信息:

    • (2)、通过反射获取目标类中所有的方法,跟前面处理字段的过程类似;

    • (3)、将每个字段或者方法解析到的元信息保存到List elements集合中,字段对应的是AutowiredFieldElement类型,方法对应的则是AutowiredMethodElement类型,等待下一步的自动装配;

    • (4)、将目标类对应的所有自动注入相关的元信息封装成InjectionMetadata,然后返回;

    buildAutowiringMetadata()方法执行完成后,会将解析得到的自动注入相关信息保存到缓存injectionMetadataCache中,如下图:

    总结:AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法的作用其实是,找到目标bean对象中的属性或者方法是否使用了@Autowired注解修饰,如果有@Autowired注解修饰,将会解析得到注解相关信息,将需要依赖注入的属性信息封装到InjectionMetadata类中,InjectionMetadata类中包含了哪些需要注入的元素及元素要注入到哪个目标类中。并将其存入到缓存injectionMetadataCache中,方便后面使用。说简单点,AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法其实就是找到那些需要自动装配的元素。

    六、AutowiredAnnotationBeanPostProcessor#postProcessProperties()源码

    前面分析到,在doCreateBean()方法中,会执行applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)方法,然后会调用到AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法,此方法主要完成解析@Autowired和@Value注解相关自动注入信息,并将解析之后的结果存入缓存中,接下来就需要自动注入属性了。

    在doCreateBean()方法执行后,接着就是执行populateBean(“userServiceImpl”)完成userServiceImpl这个bean的属性填充。

    如上图,在populateBean(“userServiceImpl”)方法中,会执行InstantiationAwareBeanPostProcessor的postProcessProperties()方法回调。

    AutowiredAnnotationBeanPostProcessor间接实现了InstantiationAwareBeanPostProcessor接口,所以会执行到

    AutowiredAnnotationBeanPostProcessor#postProcessProperties()方法,如下图:

    AutowiredAnnotationBeanPostProcessor后置处理器注入属性值是在postProcessPropertyValues()方法中实现的。一起看下AutowiredAnnotationBeanPostProcessor#postProcessProperties()方法的实现:

    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 首先尝试从缓存injectionMetadataCache中获取对应的注入元信息,如果缓存不存在,将会执行buildAutowiringMetadata()获取
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {
            // 循环InjectionMetadata的injectedElements属性,挨个调用InjectionMetadata.InjectedElement.inject方法,通过反射方式设置属性的值
            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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    postProcessProperties()方法的处理流程:

    1. 调用findAutowiringMetadata()方法,尝试从缓存injectionMetadataCache中获取对应的注入元信息,如果缓存不存在,将会执行buildAutowiringMetadata()获取;
    2. 循环InjectionMetadata的injectedElements属性,挨个调用InjectionMetadata.InjectedElement.inject方法,通过反射方式设置属性的值;

    首先会调用findAutowiringMetadata()方法,在前面已经分析过了,findAutowiringMetadata()方法将目标类对应的@Autowired注解元信息都已经解析好了,存入到缓存injectionMetadataCache中,所以 这里我们直接从缓存中获取即可。

    这里主要分析metadata.inject(bean, beanName, pvs)方法。

    public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Collection checkedElements = this.checkedElements;
        Collection elementsToIterate =
            (checkedElements != null ? checkedElements : this.injectedElements);
        if (!elementsToIterate.isEmpty()) {
            // 循环elementsToIterate, 挨个调用InjectionMetadata.InjectedElement.inject方法,通过反射方式设置属性的值;
            for (InjectedElement element : elementsToIterate) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Processing injected element of bean '" + beanName + "': " + element);
                }
                element.inject(target, beanName, pvs);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    通过AutowiredAnnotationBeanPostProcessor的源码,我们可以发现,在AutowiredAnnotationBeanPostProcessor类中,定义了AutowiredFieldElement以及AutowiredMethodElement:

    private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
        
    }
    
    private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    所以,当执行element.inject(target, beanName, pvs)方法的时候,也是调用到AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject()方法。

    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 autowiredBeanNames = new LinkedHashSet<>(1);
            Assert.state(beanFactory != null, "No BeanFactory available");
            TypeConverter typeConverter = beanFactory.getTypeConverter();
            try {
                // 解析依赖对象,实际上是从bean工厂中获取目标对象所依赖的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;
                        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);
            // 通过反射方式设置字段的值
            // 在本例中,就是注入userServiceImpl类中的userDao属性
            // bean - userServiceImpl
            // value - userDao对象
            // field - UserServiceImpl中的userDao属性
            field.set(bean, value);
        }
    }
    
    • 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

    从源码中我们看到,核心逻辑就是通过beanFactory.resolveDependency()方法从bean工厂中获取依赖的对象。跟踪一下resolveDependency()方法可以发现,底层会调用到org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate()方法,而resolveCandidate()方法内部其实是通过beanFactory.getBean(“userDao”)从bean容器中获取到userDao这个bean对象。如下图:

    依赖的userDao对象获取成功后,将会通过反射方式field.set(bean, value)设置userServiceImpl这个bean对象中的userDao属性的值。如下图:

    到这里,@Autowired就完成了依赖对象的注入工作,接着将会执行populateBean()属性填充后续的一系列处理流程。

    七、总结

    通过前面的分析,我们已经知道了@Autowired完成自动装配主要是在AutowiredAnnotationBeanPostProcessor后置处理器中实现的,主要分为两个步骤:

    • 找出需要自动装配的元素:具体实现在AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()方法;
    • 注入属性:具体实现在AutowiredAnnotationBeanPostProcessor#postProcessProperties()方法;

    通过一张图来回顾一下@Autowired自动注入的流程:

    下面我们总结一下Spring Bean的自动装配过程:

    1. 根据Class目标类类型,通过反射获取其所有的Field和Method信息,然后判断字段或者方法上面是否添加了@Autowired和@Value注解,以此来判断是否需要自动装配;
    2. 如果标注有@Autowired和@Value注解,表示需要自动装配,则会将需要自动装配的元素,封装成AutowiredFieldElement(针对字段)或AutowiredMethodElement(针对方法)对象;
    3. 调用AutowiredFieldElement或AutowiredMethodElement的inject方法,通过反射,调用容器的getBean()方法找到需要注入的Bean对象,然后注入到目标Bean中;

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    Spark Join类型和适用的场景
    元宇宙江湖里的“牛鬼蛇神”
    设计模式之--原型模式(深浅拷贝)
    使用Kubebuilder编写operator
    【踩坑系列】uniapp之h5 跨域的问题
    R语言计算时间序列数据的逐次差分(successive differences):使用diff函数计算时间序列数据的逐次差分值
    node.js学习笔记 09核心模块
    【JavaScript复习四】对象简介
    linux0.11-虚拟内存
    QT实现截屏
  • 原文地址:https://blog.csdn.net/m0_67393157/article/details/126116628