当前位置 : 主页 > 编程语言 > java >

Spring注解Autowired的底层实现原理详解

来源:互联网 收集:自由互联 发布时间:2023-01-30
目录 一、Autowired注解的用法 1、概述 2、应用 3、具体用法 二、Autowired自动装配的过程 一、Autowired注解的用法 1、概述 使用spring开发时,进行配置主要有两种方式,一是xml的方式,二是
目录
  • 一、Autowired注解的用法
    • 1、概述
    • 2、应用
    • 3、具体用法
  • 二、Autowired自动装配的过程

    一、Autowired注解的用法

    1、概述

    使用spring开发时,进行配置主要有两种方式,一是xml的方式,二是java config的方式。

    spring技术自身也在不断的发展和改变,从当前springboot的火热程度来看,java config的应用是越来越广泛了,在使用java config的过程当中,我们不可避免的会有各种各样的注解打交道,其中,我们使用最多的注解应该就是@Autowired注解了。这个注解的功能就是为我们注入一个定义好的bean

    2、应用

    应用与构造方法注入

    应用与setter方法注入

    应用与属性注入

    3、具体用法

    @Autowired

    替换:autowire属性,自动装配(按照类型装配,通过set方法,且方法可以省略)

    位置:修饰属性,set方法

    语法:@Autowired(required="true")

    注意:

    1.如果容器中没有一个可以与之匹配且required属性为true则会报异常NoSuchBeanDefinitionException

    2.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配

    3.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配,如果名称也没有匹配,则报异常NoUniqueBeanDefinitionException

    二、Autowired自动装配的过程

    首先要清楚java注解的核心其实时反射

    1、在Spring源代码当中,Autowired注解位于包org.springframework.beans.factory.annotation之中,该包的内容如下:

    核心代码如下

    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
      LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
      Class<?> targetClass = clazz;//需要处理的目标类
           
      do {
       final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
     
                /*通过反射获取该类所有的字段,并遍历每一个字段,并通过方法findAutowiredAnnotation遍历每一个字段的所用注解,并如果用autowired修饰了,则返回auotowired相关属性*/  
     
       ReflectionUtils.doWithLocalFields(targetClass, field -> {
        AnnotationAttributes ann = findAutowiredAnnotation(field);
        if (ann != null) {//校验autowired注解是否用在了static方法上
         if (Modifier.isStatic(field.getModifiers())) {
          if (logger.isWarnEnabled()) {
           logger.warn("Autowired annotation is not supported on static fields: " + field);
          }
          return;
         }//判断是否指定了required
         boolean required = determineRequiredStatus(ann);
         currElements.add(new AutowiredFieldElement(field, required));
        }
       });
                //和上面一样的逻辑,但是是通过反射处理类的method
       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.isWarnEnabled()) {
           logger.warn("Autowired annotation is not supported on static methods: " + method);
          }
          return;
         }
         if (method.getParameterCount() == 0) {
          if (logger.isWarnEnabled()) {
           logger.warn("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));
        }
       });
        //用@Autowired修饰的注解可能不止一个,因此都加在currElements这个容器里面,一起处理  
       elements.addAll(0, currElements);
       targetClass = targetClass.getSuperclass();
      }
      while (targetClass != null && targetClass != Object.class);
     
      return new InjectionMetadata(clazz, elements);
     }

    总结:

    Spring对@autowired注解的实现逻辑位于类:AutowiredAnnotationBeanPostProcessor(后置处理器)。@Autowied的本质就是new对象,因为spring的核心思想就是IOC,只是将控制权反转给了Spring框架,由它在底层通过注解或者配置文件帮我们new对象。

    到此这篇关于Spring注解Autowired的底层实现原理详解的文章就介绍到这了,更多相关Spring注解Autowired内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    上一篇:springboot publish event 事件机制demo分享
    下一篇:没有了
    网友评论