spring注解---@Autowired自动装配实现原理

目录

一、概述

语法形式:

二、实现原理


一、概述

        spring为了简化配置xml代码,在2.5版本后逐步加入了注解的方法,减少了xml文件的代码量。到3.0版本之后,甚至省略了xml文件,使用JavaConfig配置类以及annotation注解来进行依赖注入。

        @Autowired就是spring提供的注解之一,是用来替换之前写在xml文件里autowired属性的。它默认是按照类型进行匹配,自动注入一个符合要求的bean,通过set方法注入,且set方法可以省略。@Autowired可以修饰在属性以及方法上。

语法形式:

@Autowired(required="true")

        将required的属性设置为true是指所修饰的类型是必须注入,设置此属性后

        ·如果没有找到一个与之匹配的bean对象,则会抛出NoSuchBeanDefinitionException异常

        ·如果成功匹配到一个对象,则完成自动注入

        ·如果按类型匹配到多个可注入的bean对象,则会按照名称继续匹配,若按名称也未匹配成功,则会抛出NoUniqueBeanDefinitionException异常

二、实现原理

存在位置:

 由图可以看出,@Autowired位于org.springframework.beans.factory.annotation包下

@Autowired的实现,就是调用了AutowiredAnnotationBeanPostProcessor类中的方法:

1、核心方法postProcessProperties()

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 将需要自动装配的属性和方法参数封装在对象中
        InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

        try {
            // 利用反射给该对象赋值
            metadata.inject(bean, beanName, pvs);
            return pvs;
        } catch (BeanCreationException var6) {
            throw var6;
        } catch (Throwable var7) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
        }
    }

 2、findAutowiringMetadata()方法返回metadata对象

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
        String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
        InjectionMetadata metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized(this.injectionMetadataCache) {
                metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }

                    metadata = this.buildAutowiringMetadata(clazz);
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }

        return metadata;
    }

3、inject()方法完成注入

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            if (!this.checkPropertySkipping(pvs)) {
                Method method = (Method)this.member;
                Object[] arguments;
                if (this.cached) {
                    try {
                        arguments = this.resolveCachedArguments(beanName);
                    } catch (NoSuchBeanDefinitionException var8) {
                        arguments = this.resolveMethodArguments(method, bean, beanName);
                    }
                } else {
                    arguments = this.resolveMethodArguments(method, bean, beanName);
                }

                if (arguments != null) {
                    try {
                        ReflectionUtils.makeAccessible(method);
                        method.invoke(bean, arguments);
                    } catch (InvocationTargetException var7) {
                        throw var7.getTargetException();
                    }
                }

            }
        }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值