@Autowired浅析
@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浅析相关推荐
- Java应用服务系统安全性,签名和验签浅析
1 前言 随着互联网的普及,分布式服务部署越来越流行,服务之间通信的安全性也是越来越值得关注.这里,笔者把应用与服务之间通信时,进行的的安全性相关,加签与验签,进行了一个简单的记录. 2 安全性痛点 ...
- Springboot整合redis实现缓存及其缓存运行原理浅析
声明:小白,学习阶段,主要目的是为了记录学习过程,本文仅供参考,如有不足的地方欢迎指出讨论交流 本文基于Springboot2.1.3版本开发: 准备阶段 首先是pom.xml文件所需的依赖: < ...
- 浅析 JavaScript 中的 函数 uncurrying 反柯里化
柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是 ...
- 浅析Python中bytes和str区别
本博转载自:Chown-Jane-Y的浅析Python3中的bytes和str类型 Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示, ...
- Dubbo的使用及原理浅析.
前面几个博文中关于SSM 框架已经搭建完成, 这里来讲下项目中使用到的Dubbo以及自己了解到的关于Dubbo的一些知识. Dubbo是什么? Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天 ...
- 学习《Linux设备模型浅析之设备篇》笔记(深挖一)
这篇文章既然说了是浅析,那就是跳过了一些东西,我们把这些跳过的东西给它尽可能的补回来 今天登陆 lxr.free-electrons.com 发现内核版本已经升级到3.15了,那以后都使用3.15的源 ...
- 学习《Linux设备模型浅析之设备篇》笔记(一)
最近在学习Linux设备模型,前面几篇文章也是读这篇的时候遇到问题,然后为了搞清楚先转去摸索才写出来的. 当然了,刚开始是先读到<Linux那些事儿之我是Sysfs>,搞不清楚才去读的&l ...
- Spring中@Autowired注解、@Resource注解的区别
Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...
- Spring注解@Component、@Repository、@Service、@Controller,@Autowired、@Resource用法
一.Spring定义bean,@Component.@Repository.@Service 和 @Controller Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥 ...
最新文章
- contain_of宏定义
- Android L 使用ART能提高多少性能?
- python图像拼接过渡自然_python实现图像拼接功能
- ZedGraph怎样在双击图形后添加箭头标记
- 大神接棒,YOLOv4来了!
- 网站程序IIS布署问题备忘录
- 如何在CISCO PIX上实现×××步骤?
- dao层和service层和control_最受欢迎Java数据库访问框架(DAO层)
- java实例变量,局部变量,类变量和final变量
- 企业创新系列之:雨巷邂逅
- python的前世今生
- 安徽安全员B考试最新多选题库(2)
- weblogic下载、安装、配置
- idea使用svn拉取项目代码_IDEA使用svn下载项目,并配置svn项目和tomcat进行访问
- 基于Python实现可以进制转换和计算阶乘的科学计算器
- mysql 法语字符比较_法语词典哪种比较好?
- css图片横向压缩,【css样式生成 图片合并压缩工具】Sprite,你值得拥有
- 超详细的计算机视觉学习书籍pdf汇总(涉及CV、深度学习、多视图几何、SLAM、点云处理等)
- 知识图谱嵌入经典方法(Trans系列、KG2E)
- 人民币转换---java代码实现