@Autowired的实现原理
1.了解@Autowired
在这之前你得了解SpringIOC容器的相关知识。
含义:@Autowired表示某个属性是否需要进行依赖注入 ,可以写在属性和方法上。注解中的required属性默认为ture,表示如果没有对象注入给属性则抛出异常
自动装配有两种实现方式:通过xml配置的方式与注解的方式。
@Autowired相比于xml配置方式
替换:autowire属性,自动装配(按照类型装配,通过set方法,且方法可以省略)
位置:修饰属性,set方法
语法:@Autowired(required="true")
注意:
1.如果容器中没有一个可以与之匹配且required属性为true则会报异常 NoSuchBeanDefinitionException
2.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配
3.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配,如果名称也没有匹配,则报异常 NoUniqueBeanDefinitionException
2.底层实现原理:
- 位置
@Autowired的源码
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;}//判断是否指定了requiredboolean required = determineRequiredStatus(ann);currElements.add(new AutowiredFieldElement(field, required));}});//和上面一样的逻辑,但是是通过反射处理类的methodReflectionUtils.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);}
结合注释就能看懂它做的事情了。 postProcessMergedBeanDefinition()方法的作用是找到需要自动装配的元素,构建元数据信息,然后封装到AutowiredFieledElement或AutowiredMethodElement中,然后在调用其中的inject方法,通过反射,调用容器的getBean()方法找到需要注入的Bean对象,然后注入到Bean中。
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);metadata.checkConfigMembers(beanDefinition);}
@Autowired的实现原理相关推荐
- @Autowired注解实现原理
在讨论代码细节之前,我们再来了解下基础知识.Spring管理可用于整个应用程序的Java对象bean.他们所在的Spring容器,被称为应用程序上下文.这意味着我们不需要处理他们的生命周期(初始化,销 ...
- Spring @AutoWired实现原理
昨晚在使用JUnit测试AOP实现时,出现一个问题.在JUnit使用@AutoWired注入某一个对象,Bean Factory里面有该接口的多个实现,Spring不报错,而始终注入的是一个实现类的实 ...
- 关于@Autowired后Spring无法注入的问题
1.对于新手来说,最明显的不过是在applicationContext.xml文件上没有加<context:component-scan base-package="com.xxx&q ...
- @autowired注解注入为null_Spring @Autowired 注解自动注入流程是怎么样?
面试中碰到面试官问:"Spring 注解是如果工作的?",当前我一惊,完了这不触及到我的知识误区了吗?,还好我机智,灵机一动回了句:Spring 注解的工作流程倒还没有看到,但是我 ...
- 你所不知道的Spring的@Autowired实现细节
相信很多Java开发都遇到过一个面试题:Resource和Autowired的区别是什么?这个问题的答案相信基本都清楚,但是这两者在Spring中是如何实现的呢?这就要分析Spring源码才能知道了. ...
- java线程池的使用例子,不愧是大佬
京东Java研发岗一面(基础面,约1小时) 自我介绍,主要讲讲做了什么和擅长什么 springmvc和spring-boot区别 @Autowired的实现原理 Bean的默认作用范围是什么?其他的作 ...
- 一个星期+4轮面试终拿下offer,进阶学习
京东Java研发岗一面(基础面,约1小时) 自我介绍,主要讲讲做了什么和擅长什么 springmvc和spring-boot区别 @Autowired的实现原理 Bean的默认作用范围是什么?其他的作 ...
- hashmap应用场景_京东4面(Java研发):事务隔离+乐观锁+HashMap+秒杀设计+微服务
一面(基础面:约1小时) 自我介绍,主要讲讲做了什么和擅长什么 springmvc和spring-boot区别 @Autowired的实现原理 Bean的默认作用范围是什么?其他的作用范围? 索引是什 ...
- java教程传智播客,面试真题解析
01 阿里中间件(四面,Java岗) 1.1 Java中间件一面 技术一面考察范围 重点问了Java线程锁:synchronized 和ReentrantLock相关的底层实现 线程池的底层实现以及常 ...
最新文章
- 深入理解Spring系列之六:bean初始化
- 职场:5种幼稚表现,好多工作十年的人还在犯
- oracle批输入命令流,ORACLE对表批处理操作
- sor迭代法matlab实例,Jacobi G-S SOR迭代法在matlab中例子.pdf
- python字符串写入excel-python 将数据写入excel
- 题目1025:最大报销额
- 娓娓道来Promise
- mysql9索引实战_mysql 索引实战 | 学步园
- 【开源项目】使用FFMPEG解析H264编码为YUV格式
- pip 源使用阿里云镜像加速
- LINUX下载并编译sqlite
- winform 线程 句柄不断增加_多线程讲解
- 好用的Windows屏幕取色器 ColorWanted
- webgl图库研究(包括BabylonJS、Threejs、LayaboxJS、SceneJS、ThingJS等框架的特性、适用范围、支持格式、优缺点、相关网址)
- 计算机 电脑 整机 加密,如何加密文件夹
- SQLServer笔试题
- PostgreSQL集群篇——PostgreSQL的配置文件解析
- 【综合复习_网络部分】
- 如何使用轻量应用服务器自带的Cloudreve应用镜像搭建属于自己的云网盘?
- 迭代决策树GBDT(MART)【理论】