当前位置: 首页 > news >正文

Spring中@Autowired注解实现原理

        @Autowired是一种注解,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作,@Autowired标注可以放在成员变量上,也可以放在成员变量的set方法上,也可以放在任意方法上表示,自动执行当前方法,如果方法有参数,会在IOC容器中自动寻找同类型参数为其传值。

@Autowired参数意义

@Autowired注解,只有一个required元素,默认是true,也是就是说这个值能改为false。true和false的意义不同。

require=ture 时,表示解析被标记的字段或方法,一定有对应的bean存在。
require=false 时,表示解析被标记的字段或方法,没有对应的bean存在不会报错。

@Autowired源码

public @interface Autowired {
    boolean required() default true;
}

 @Autowired原理

        通过查看@Autowired注解注释文档,可以了解到加载放在了AutowiredAnnotationBeanPostProcessor。而AutowiredAnnotationBeanPostProcessor是何时来的又是怎么执行去加载@Autowired呢?
首先要知道再执行AbstractApplicationContext#refresh()方法时会执行obtainFreshBeanFactory()方法,而这个方法执行时,会在
DefaultListableBeanFactory#beanDefinitionNames数组中添加internalAutowiredAnnotationProcessor。而internalAutowiredAnnotationProcessor是和AutowiredAnnotationBeanPostProcessor被一起注册到registerPostProcessor中。

if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
    def.setSource(source);
    beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

项目启动会自动执行refresh方法中的registerBeanPostProcessors(beanFactory)方法。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

getBeanNamesForType 是对前面加载的internalAutowiredAnnotationProcessor进行转换成AutowiredAnnotationBeanPostProcessor然后把返回值postProcessorNames转为priorityOrderedPostProcessors然后注册到registerBeanPostProcessors中 

public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
         ...
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
         ...
    }
  private static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }
 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        // Remove from old position, if any
        this.beanPostProcessors.remove(beanPostProcessor);
        // Track whether it is instantiation/destruction aware
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            this.hasInstantiationAwareBeanPostProcessors = true;
        }
        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            this.hasDestructionAwareBeanPostProcessors = true;
        }
        // Add to end of list
        this.beanPostProcessors.add(beanPostProcessor);
    }

refresh()执行完registerBeanPostProcessors 方法后,继续执行finishBeanFactoryInitialization(beanFactory);

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        ...
        // Instantiate all remaining (non-lazy-init) singletons.
        beanFactory.preInstantiateSingletons();
    }

这里spring会创建所需要的bean,一般在controller层中引入的service也会在此时依赖加载和创建。

public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                       ...
            getBean(beanName);
                      ...
        }

当执行到我们自定义的controller层时,会在getBean中进行执行autowire解析。

   public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }
  protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
              return createBean(beanName, mbd, args);
}
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
      ...
      doCreateBean(beanName, mbdToUse, args);
      ...
}

而doCreateBean是真正的创建bean实现,在创建的时候调用了applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {
              ...
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            ...
    }

终于在applyMergedBeanDefinitionPostProcessors中看到了BeanPostProcessor

  protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }

getBeanPostProcessors方法获取的就是上文中添加的AutowiredAnnotationBeanPostProcessor的集合beanPostProcessors
则执行我们的想看到的AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

  public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }

findAutowiringMetadata查询这个beanName中,是否有

  private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
         ...
        metadata = buildAutowiringMetadata(clazz);
         ...
    }
 private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        Class<?> targetClass = clazz;
                AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
                if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    boolean required = determineRequiredStatus(ann);
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new AutowiredMethodElement(method, required, pd));
                }
            });

            elements.addAll(0, currElements);
            targetClass = targetClass.getSuperclass();
        }
        return new InjectionMetadata(clazz, elements);
    }

findAutowiredAnnotation(bridgedMethod)找到这个类的autowire注解的类,添加到InjectionMetadata对象中。然后在checkConfigMembers方法中又注册到beanDefinition中。

 @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }
 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;
    }

相关文章:

  • 干货!手把手教你穿透内网
  • 人家网站都免费了,你还用Python去爬?
  • 2023年上半年软考中、高级 了解一下
  • Android 13 新特性及适配指南
  • 分布式事务Seata源码解析十:AT模式回滚日志undo log详细构建过程
  • 链路状态路由协议 OSPF (一)
  • 利用Redis实现分布式长效缓存
  • c# 的一些简单用法
  • 【QT开发专题-天气预报】16.更新 UI 界面
  • D-star算法简介及相关思考
  • Java POI Word 转 PDF
  • DASCTF X GFCTF 2022十月 Misc
  • 10月工作经验总结
  • 点云地面滤波--一种改进的渐进式不规则三角网加密地面滤波算法
  • 新的3D地图制图技术改变了全球定位的游戏规则
  • 分享一款快速APP功能测试工具
  • AWS实战 - 利用IAM对S3做访问控制
  • css选择器
  • es6(二):字符串的扩展
  • magento 货币换算
  • Protobuf3语言指南
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • Travix是如何部署应用程序到Kubernetes上的
  • 测试开发系类之接口自动化测试
  • 前嗅ForeSpider教程:创建模板
  • 使用Gradle第一次构建Java程序
  • 微服务框架lagom
  • 我看到的前端
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • Nginx实现动静分离
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (LeetCode C++)盛最多水的容器
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)Oracle存储过程编写经验和优化措施
  • (转)重识new
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .Net Core 中间件验签
  • .net 无限分类
  • .NET 中创建支持集合初始化器的类型
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET导入Excel数据
  • .net实现客户区延伸至至非客户区
  • .net专家(张羿专栏)
  • /etc/sudoer文件配置简析
  • ::什么意思
  • @AutoConfigurationPackage的使用
  • @JsonSerialize注解的使用
  • [AutoSar]BSW_Memory_Stack_003 NVM与APP的显式和隐式同步