@Autowired浅析

首先放几段代码和几个问题,带着思考去看接下来的结论

第一个问题

第一段代码:容器初始化完毕,控制台是否会打印(“This is a method from TeachService”)这句话?

@Service
public class StudyService {public void setTeacherService(TeachService teacherService){teacherService.teach();}}@Service
public class TeachService {public void teach(){System.out.println("This is a method from TeachService");}}

答案是会,但是这里我是做了一个细节上的配置,正常情况下,即默认情况是不会打印的,稍后细说。

第二个问题

说起@Autowired注解,大家想到的就是byType,那么看下面的代码。

//声明一个接口
public interface People {void showIdentity();
}
//写两个实现类,都注入到spring容器中
@Service
public class StudyService implements People {@Overridepublic void showIdentity() {System.out.println("I am a student");}
}@Service
public class TeachService implements People {@Overridepublic void showIdentity() {System.out.println("I am a teacher");}
}
//使用另外的bean注入People类型,请注意,这里注入的类型是接口,变量名使用的是studyService
//如果按照byType的理解,容器初始化时应该会报错,同一个type找到多个bean,不知道注入哪个
@Service
public class Leader {@AutowiredPeople studyService;public void showYourIdentity(){studyService.showIdentity();}
}

其实呢,看下图运行成果

第三个问题

读过源码的同学可能了解过populateBean方法里有一段判断逻辑

这里的逻辑是判断bean的注入类型是否为byName或者byType,看到图中的值,相信大家都知道,是不会进这个if分支的,那么是为什么呢?接下来放一段官网对于注入的一个解释。

下面是对于上面的一个部分翻译

模式 解释
no 非自动装配,bean的应用需要通过ref元素定义
byName 按属性名称自动装配。Spring容器会寻找与需要自动实现的属性同名的bean。
byType 如果容器中恰好存在该属性类型的一个bean,则允许该属性被自动调用。如果存在多个,就会抛出一个异常,这表明不能对该bean使用byType自动装配。
constructor 类似于byType,但适用于构造函数参数。

问题解答

按照上述官网解释,如果@Autowired注解真的是像大部分网上所说的byType,那么我第二个问题的代码怎么可能运行成功呢?接下来用spring的后置处理器去获取一下StudyService的BeanDefinition对象,通过BeanDefinition对象查看装配类型究竟是什么吧!

@Configuration
public class MyPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {GenericBeanDefinition s = (GenericBeanDefinition) beanFactory.getBeanDefinition("studyService");System.out.println("默认装配类型:"+s.getAutowireMode());}
}

由上图可知@Autowired的装配类型为0,即官网所说的NO-非自动装配。

有的人可能疑问了,为什么叫非自动装配?spring明明帮我们把需要的类创建出来了呀,这个问题接下来会解释。

先回顾第一个问题,为什么明明没有使用注解和xml,set方法中的bean依旧注入成功了呢?依旧用到了后置处理器。上代码

@Configuration
public class MyPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {GenericBeanDefinition s = (GenericBeanDefinition) beanFactory.getBeanDefinition("studyService");//重点在这里,通过后置处理器得到BeanDefinition对象后,修改autowireMode的值为2,即byTypes.setAutowireMode(2);}
}

怎么做到的已经展示完了,接下来结合这一和二的内容,给大家做一个简短的解释。

首先大家所理解的自动装配,是以开发人员的角度来说:我是一个开发,spring帮我把TeachService创建并注入到了StudyService中,这个过程中,“我”并没有参与什么,只是声明了一个注解。

这就好比:

​以前我们大家吃饭,需要自己买菜->做饭->吃饭->洗碗,做完整个周期性的任务才算完成;

​现在有了餐馆(spring),我们只需要到餐馆(spring)声明我要吃鱼香肉丝,在(买菜->做饭->吃饭->洗 碗)这个周期中,我们只需做到“吃饭”即可。

请注意,上述描述的角度是我->餐馆的顾客|开发人员->spring的使用者

不知道大家能不能明白我所说的。

接下来的是我个人理解了,可能有所错误,大家可以共同探讨!!!

我理解的自动装配是相对于spring角度,也就是餐馆角度;

当我走进餐馆时(我使用setTeachService方法),老板看到我就“觉得”我想要鱼香肉丝(对应autowiredMode修改为2之后,spring容器发现setTeachService方法时),并没有问我是否真的需要(比如我就是想单纯实现一个setTeachService方法自己用呢,对吧),就直接给我上了一盘鱼香肉丝饭。

简单的来说:在autowiredMode不等于0时,当开发人员提供了一个spring认可的注入方式,即set和construct形式时,spring会直接注入这两种DI形式中的bean(前提是bean)

这里插一个小知识点

官方文档说明了,DI(依赖注入)有两种主要的变体,即基于构造器的依赖注入和基于setter的依赖注入。

即使是常用的@Autowired注解,也是通过反射生成set方法进行的赋值。

本菜鸟也是刚入行三年,如果上述有什么问题,大家可以留言,我会积极改正和学习的。

@Autowired浅析相关推荐

  1. Java应用服务系统安全性,签名和验签浅析

    1 前言 随着互联网的普及,分布式服务部署越来越流行,服务之间通信的安全性也是越来越值得关注.这里,笔者把应用与服务之间通信时,进行的的安全性相关,加签与验签,进行了一个简单的记录. 2 安全性痛点 ...

  2. Springboot整合redis实现缓存及其缓存运行原理浅析

    声明:小白,学习阶段,主要目的是为了记录学习过程,本文仅供参考,如有不足的地方欢迎指出讨论交流 本文基于Springboot2.1.3版本开发: 准备阶段 首先是pom.xml文件所需的依赖: < ...

  3. 浅析 JavaScript 中的 函数 uncurrying 反柯里化

    柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是 ...

  4. 浅析Python中bytes和str区别

    本博转载自:Chown-Jane-Y的浅析Python3中的bytes和str类型 Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示, ...

  5. Dubbo的使用及原理浅析.

    前面几个博文中关于SSM 框架已经搭建完成, 这里来讲下项目中使用到的Dubbo以及自己了解到的关于Dubbo的一些知识. Dubbo是什么? Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天 ...

  6. 学习《Linux设备模型浅析之设备篇》笔记(深挖一)

    这篇文章既然说了是浅析,那就是跳过了一些东西,我们把这些跳过的东西给它尽可能的补回来 今天登陆 lxr.free-electrons.com 发现内核版本已经升级到3.15了,那以后都使用3.15的源 ...

  7. 学习《Linux设备模型浅析之设备篇》笔记(一)

    最近在学习Linux设备模型,前面几篇文章也是读这篇的时候遇到问题,然后为了搞清楚先转去摸索才写出来的. 当然了,刚开始是先读到<Linux那些事儿之我是Sysfs>,搞不清楚才去读的&l ...

  8. Spring中@Autowired注解、@Resource注解的区别

    Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...

  9. Spring注解@Component、@Repository、@Service、@Controller,@Autowired、@Resource用法

    一.Spring定义bean,@Component.@Repository.@Service 和 @Controller Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥 ...

最新文章

  1. contain_of宏定义
  2. Android L 使用ART能提高多少性能?
  3. python图像拼接过渡自然_python实现图像拼接功能
  4. ZedGraph怎样在双击图形后添加箭头标记
  5. 大神接棒,YOLOv4来了!
  6. 网站程序IIS布署问题备忘录
  7. 如何在CISCO PIX上实现×××步骤?
  8. dao层和service层和control_最受欢迎Java数据库访问框架(DAO层)
  9. java实例变量,局部变量,类变量和final变量
  10. 企业创新系列之:雨巷邂逅
  11. python的前世今生
  12. 安徽安全员B考试最新多选题库(2)
  13. weblogic下载、安装、配置
  14. idea使用svn拉取项目代码_IDEA使用svn下载项目,并配置svn项目和tomcat进行访问
  15. 基于Python实现可以进制转换和计算阶乘的科学计算器
  16. mysql 法语字符比较_法语词典哪种比较好?
  17. css图片横向压缩,【css样式生成 图片合并压缩工具】Sprite,你值得拥有
  18. 超详细的计算机视觉学习书籍pdf汇总(涉及CV、深度学习、多视图几何、SLAM、点云处理等)
  19. 知识图谱嵌入经典方法(Trans系列、KG2E)
  20. 人民币转换---java代码实现

热门文章

  1. 为什么这些年都不快乐
  2. protege的下载
  3. Linux 下 QT 安卓开发环境搭建
  4. WAP 2.0 VS WEB 2.0
  5. 100天搞定机器学习(100-Days-Of-ML)(一)数据预处理
  6. 数据库设计之数据字典的使用与设计
  7. vue upload上传图片
  8. USB Type A/B/C基本知识和各版本区别
  9. opencv 实现 Photoshop 亮度 对比度 调节功能
  10. python在手机上可以画图吗_python可以画图么