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

目录
  • 一、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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot Application核心注解详解

    目录 @SpringBootApplication @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan @SpringBootApplication @SpringBootApplication 是一个“三体”结构,实际上它是一个复合 Annotation: ​ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @In

  • Spring注解与P/C命名空间超详细解析

    目录 注解实现自动装配 @Autowire注解 @Qualifier注解 @Resource注解 @Component @Scope @ComponentScan @Bean @Configuration @Value P命名空间注入 C命名空间注入 Spring开发包名解释 Java方式配置 注解实现自动装配 @Autowire注解 @Autowire注解,自动装配通过类型,名字如果Autowire不能唯一自动装配上属性, 则需要通过@Qualifier(value=“xxx”) 配置: 导入

  • 一文带你了解SpringBoot中常用注解的原理和使用

    目录 @AutoConfiguration @Import @ConfigurationProperties @AutoConfiguration 读取所有jar包下的 /META-INF/spring.factories 并追加到一个 LinkedMultiValueMap 中.每一个url中记录的文件路径如下: file:/C:/Users/wangchao/apache-maven-3.5.0/repo/com/baomidou/mybatis-plus-boot-starter/3.5.

  • Spring中@order注解用法实战教程

    目录 前言 一.观察@order源码 二.@order实战 三.@order失效原因 四.解决排序问题 五.排序源码分析 六.@AutoConfigureOrder 总结 前言 @order注解是spring-core包下的一个注解,@Order的作用是定义Spring IOC容器中Bean的执行顺序的优先级(这里的顺序也可以理解为存放到容器中的先后顺序).开发过程当中有时候经常会出现配置依赖关系,例如注入A对象使用了 @ConditionalOnBean(B.class),意思是要求容器当中必

  • Spring框架基于注解的AOP之各种通知的使用与环绕通知实现详解

    目录 一.基于注解的AOP之各种通知的使用 二.基于注解的AOP之环绕通知 一.基于注解的AOP之各种通知的使用 1.在切面中,需要通过指定的注解将方法标识为通知方法 @Before:前置通知,在目标对象方法执行之前执行 @After:后置通知,在目标对象方法的finally子句中执行 @AfterReturning:返回通知,在目标对象方法返回值之后执行 @AfterThrowing:异常通知,在目标对象方法的catch子句中执行 声明重用写入点表达式 @Pointcut("execution

  • 浅析Spring基于注解的AOP

    目录 一.准备工作 二.基于注解的AOP之前置通知 三.基于注解的AOP之切入点表达式的语法和重用以及获取连接点的信息 ①切入点表达式的语法 ②获取连接点的信息 ③重用写入点表达式 一.准备工作 ①创建一个Maven工程 ②添加依赖 在IOC所需依赖基础上再加入下面依赖即可: <!-- spring-aspects会帮我们传递过来aspectjweaver --> <dependency> <groupId>org.springframework</groupId

  • Spring @Conditional注解示例详细讲解

    目录 前言: 示例: 标注在方法上: 标注在类上: 多个条件类: 前言: @Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean. @Conditional的定义: //此注解可以标注在类和方法上 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditi

  • Spring中Transactional注解使用的心得(推荐)

    事务特性 @Transactional注解是用于事务控制的,需要知道事务的ACID特征:即原子性(Atomicity,或称不可分割性).一致性(Consistency).隔离性(Isolation,又称独立性).持久性(Durability). 事务是用来控制数据的ACID特性的,用于保证数据的正确性和完整性. @Transactional注解有两种使用方式: (1)标注在类上面:当作用于类上时,该类的所有public方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别

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

    目录 一.Autowired注解的用法 1.概述 2.应用 3.具体用法 二.Autowired自动装配的过程 一.Autowired注解的用法 1.概述 使用spring开发时,进行配置主要有两种方式,一是xml的方式,二是java config的方式. spring技术自身也在不断的发展和改变,从当前springboot的火热程度来看,java config的应用是越来越广泛了,在使用java config的过程当中,我们不可避免的会有各种各样的注解打交道,其中,我们使用最多的注解应该就是@

  • Spring注解方式防止重复提交原理详解

    Srping注解方式防止重复提交原理分析,供大家参考,具体内容如下 方法一: Springmvc使用Token 使用token的逻辑是,给所有的url加一个拦截器,在拦截器里面用java的UUID生成一个随机的UUID并把这个UUID放到session里面,然后在浏览器做数据提交的时候将此UUID提交到服务器.服务器在接收到此UUID后,检查一下该UUID是否已经被提交,如果已经被提交,则不让逻辑继续执行下去-** 1 首先要定义一个annotation: 用@Retention 和 @Targ

  • spring boot微服务自定义starter原理详解

    这篇文章主要介绍了spring boot微服务自定义starter原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 使用spring boot开发微服务后,工程的数量大大增加(一定要按照领域来切,不要一个中间件客户端包一个),让各个jar从开发和运行时自包含成了一个重要的内容之一.spring boot starter就可以用来解决该问题(没事启动时别依赖于applicationContext.getBean获取bean进行处理,依赖关系

  • 对ArrayList和LinkedList底层实现原理详解

    1.说一下 ArrayList 底层实现方式? ①ArrayList 通过数组实现,一旦我们实例化 ArrayList 无参数构造函数默认为数组初始化长度为 10 ②add 方法底层实现如果增加的元素个数超过了 10 个,那么 ArrayList 底层会新生成一个数组,长度为原数组的 1.5 倍+1,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中.当新数组无法容纳增加的元素时,重复该过程.是一旦数组超出长度,就开始扩容数组. 扩容数组调用的方法 Arrays.copyO

  • Python字典底层实现原理详解

    在Python中,字典是通过散列表或说哈希表实现的.字典也被称为关联数组,还称为哈希数组等.也就是说,字典也是一个数组,但数组的索引是键经过哈希函数处理后得到的散列值.哈希函数的目的是使键均匀地分布在数组中,并且可以在内存中以O(1)的时间复杂度进行寻址,从而实现快速查找和修改.哈希表中哈希函数的设计困难在于将数据均匀分布在哈希表中,从而尽量减少哈希碰撞和冲突.由于不同的键可能具有相同的哈希值,即可能出现冲突,高级的哈希函数能够使冲突数目最小化.Python中并不包含这样高级的哈希函数,几个重要

  • HashMap底层实现原理详解

    一.快速入门 示例:有一定基础的小伙伴们可以选择性的跳过该步骤 HashMap是Java程序员使用频率最高的用于映射键值对(key和value)处理的数据类型.随着JDK版本的跟新,JDK1.8对HashMap底层的实现进行了优化,列入引入红黑树的数据结构和扩容的优化等.本文结合JDK1.7和JDK1.8的区别,深入探讨HashMap的数据结构实现和功能原理. Java为数据结构中的映射定义了一个接口java.uti.Map,此接口主要有四个常用的实现类,分别是HashMap,LinkedHas

  • Spring注解实现Bean自动装配示例详解

    何为自动装配 自动装配是 Spring 满足 bean 依赖的一种方式. 在使用 Spring 配置 bean 时,我们都要给配置的 bean 的属性设置一个值,如果不手动设置则都是空.而自动的好处就在于,我们不用手动去设置一个值,spring 会在上下文中自动寻找并装配合适的值. 本文主要介绍了Spring注解Bean自动装配的相关内容,下面话不多少了,来一起看看详细的介绍吧 使用须知: 1.导入约束:context约束 2.配置注解的支持: context:annotation-config

  • Spring注解配置IOC,DI的方法详解

    目录 1.注解 @Component 第一步:在 applicationContext.xml 中引入命名空间 第二步:在 applicationContext.xml 文件中引入注解扫描器 第三步:在 Person 类中添加注解@Component 第四步:测试 2.@Repository @Service @Controller 3.注解@Resource 4.注解 @Autowired 第一步:创建接口 PersonDao 第二步:创建一个接口实现类 PersonDaoImplOne 第三

  • Spring注解@Autowired背后实现的原理

    目录 前言 使用spring开发时,进行配置主要有两种方式,一是xml的方式,二是java config的方式. spring技术自身也在不断的发展和改变,从当前springboot的火热程度来看,java config的应用是越来越广泛了,在使用java config的过程当中,我们不可避免的会有各种各样的注解打交道,其中,我们使用最多的注解应该就是@Autowired注解了.这个注解的功能就是为我们注入一个定义好的bean. 那么,这个注解除了我们常用的属性注入方式之外还有哪些使用方式呢?它

  • Spring JdbcTemplate整合使用方法及原理详解

    基本配置 JdbcTemplate基本用法实际上很简单,开发者在创建一个SpringBoot项目时,除了选择基本的Web依赖,再记得选上Jdbc依赖,以及数据库驱动依赖即可,如下: 项目创建成功之后,记得添加Druid数据库连接池依赖(注意这里可以添加专门为Spring Boot打造的druid-spring-boot-starter,而不是我们一般在SSM中添加的Druid),所有添加的依赖如下: <dependency> <groupId>com.alibaba</gro

随机推荐