Autowired的底层实现原理_autowrited-程序员宅基地

技术标签: spring  spring boot  java  开发语言  

一、Autowired注解的用法

1、概述

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

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

2、应用:

2.1、应用与构造方法注入

2.2、应用与setter方法注入

2.3、应用与属性注入

 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对象。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_49187233/article/details/127540946

智能推荐

前端组件库-程序员宅基地

文章浏览阅读101次。0. 前端自动化前端构建工具gulp - The streaming build systemgrunt - the JavaScript Task Runner前端模块管理器Bower - A package manager for the webBrowserifyComponentDuoRequireJSSea.jscs..._webix ejs node.js

Google maps API开发-程序员宅基地

文章浏览阅读215次。被房产网的地图搜索快给搞疯了,从网上搜的,留着以后学习用注:经纬度的查询,找了半天,终于找着活神仙了,(*^__^*) 嘻嘻……1.经纬度查询工具:http://www.playgoogle.com/googlemap/tool1.html 2.http://www.playgoogle.com/catalog.asp?cate=1 3.利用 Google Maps 查詢地..._maps.tr

给最后一个li增加样式-程序员宅基地

文章浏览阅读508次。用Jquery来写:$(".rec3 li:last").css("margin-right", "0px");说明:  1、$(".rec3 li:last")选择器下的最后一个元素  2、增加样式转载于:https://www.cnblogs.com/cxnian/p/7449760.html..._js判断最最后一个li标签上添加一些css

十大免费杀毒软件大盘点-程序员宅基地

文章浏览阅读1.1k次。1.Fortinet 4.1.0杀毒软件Fortinet,中国用户称之为“飞塔”,来自美国加州Sunnyvale。Fortinet具有多层网络威胁防御体系,在监控水平和查 杀能力上,并不逊于大家常用的其它免费杀毒软件。在如今杀毒软件“免费”大潮的冲击下,“飞塔”也推出了Forti Client免费版,无需任何序列号即可安装并享用全功能:防病毒、防火墙、网页过滤、广域网优化..._杀毒软件带雨

VC++动态链接库(DLL)编程(二)--非MFC DLL-程序员宅基地

文章浏览阅读63次。4.非MFC DLL4.1一个简单的DLL  第2节给出了以静态链接库方式提供add函数接口的方法,接下来我们来看看怎样用动态链接库实现一个同样功能的add函数。  如图6,在VC++中new一个Win32 Dynamic-Link Library工程dllTest(单击此处下载本工程附件)。注意不要选择MFC AppWizard(dll),因为用MF..._vc写非mfc dll

【编译原理】语法分析LL(1)分析法的FIRST和FOLLOW集-程序员宅基地

文章浏览阅读542次。  近来复习编译原理,语法分析中的自上而下LL(1)分析法,需要构造求出一个文法的FIRST和FOLLOW集,然后构造分析表,利用分析表+一个栈来做自上而下的语法分析(递归下降/预测分析),可是这个FIRST集合FOLLOW集看得我头大。。。  教课书上的规则如下,用我理解的语言描述的:任意符号α的FIRST集求法:1. α为终结符,则把它自身加..._构造follow集需要用什么函数

随便推点

关于Unity中场景的导入与导出(专题九)-程序员宅基地

文章浏览阅读847次。Unity场景场景虽然是由场景美术做好的,但是我们经常需要自己去导导出以及从别的项目导入,所以我们需要对场景的导入和导出有一个详细的了解1: 场景是由美术人员搭建完成后提交给程序;2: 场景一般包括了地形, 创建物体, 光源, 天空盒,与雾等;3: 场景不包含任何逻辑4: 程序员要能熟练的导入与导出其他项目的场景;场景导出和导入思路把Unity4.X的场景文件..._unity 默认天空导出

linux 绝对路径格式化,相对/绝对路径,cd命令,mkdir/rmdir命令,rm命令-程序员宅基地

文章浏览阅读458次。一、相对路径和绝对路径什么是文件路径?就是文件存放的具体位置,你告诉系统文件位置,系统就能找到这个文件。在Linux中,存在绝对路径和相对路径。绝对路径:一定是从根目录/写起,比如:/etc/sysconfig/network-config/ifcfg-ens3相对路径:路径不是由根目录/写起,比如:先进入到/etc,然后在进入sysconfig,执行结果如下二、CD命令1、命令cd(change..._能不能使用绝对路径rmdir -p /usr/local/itheima/tomcat ? 为什么?

内网穿透教程-程序员宅基地

文章浏览阅读5.3w次,点赞31次,收藏243次。目录内网穿透教程前言内网穿透的方式第一种方式,拥有公网ip方法第二种方式,使用frp方法下载frp工具内网穿透教程前言所谓内网穿透,也即是局域网能够直接通过公网的ip去访问,极大的方便用户的日常远程的一些操作的使用。比如nas的远程访问,个人博客的搭建等等。端口映射概念:见名知意,就是将端口做映射,而这个映射是在不同的IP的端口进行映射,比如下图这个部分有三个需要注意的,第一是外部端口,第二是内部端口,第三是ip地址。或许就有人要问了,不是不同ip下的端口进行映射吗?怎么还少了外部的ip。上_内网穿透

NR/5G - SUL_5g sul-程序员宅基地

文章浏览阅读5.4k次。SUL,supplimentary uplink,简单翻译过来为补充上行的意思。在38.101 Table 5.2-1中,将部分Band定义为SUL。为什么需要引入SUL呢? 通常,基站的最大发射功率一般大于终端的最大发射,因此下行覆盖一般要大于上行覆盖,如38.300中图B.1-1所示。传输损耗与载波频率成反比,因此从SUL Band选取的频率范围来看,都是低于2GHz。 SUL和NR UL的配置一样,同样包含Ini..._5g sul

Oracle参数open_cursors和session_cached_cursor详解-程序员宅基地

文章浏览阅读90次。1234567891011121314SQL>showparameteropen_cursors--每个session(会话)最多能同时打开多少个cursor(游标)NAMETYPEV..._select name, value from parameter where name like 'open_cursors';

JS · \r\n被转义导致出错-程序员宅基地

文章浏览阅读4k次。拼接字符串时,\r\n被转义成换行导致出错,不想让它转义的方法就是把\r\n替换成空res.data.forEach(m =&gt; { m = m.replace(/[\r\n]/g, ''); this.richText = this.richText + "&lt;img src=\"data:image/jpeg;base64," + m + "\"&gt;";})复制代码..._前端输入得\n被转

推荐文章

热门文章

相关标签