1.Spring注解之@Autowired、注注解@Qualifier、解源@Resource、原理@Value
2.@Autowired竟然能玩出这么多花样,注注解涨见识了
3.@autowired注解有什么用?解源
4.注解@Autowired和@Resource的区别总结
5.Spring源码Autowired注入流程
6.autowired和resource注解的区别
Spring注解之@Autowired、@Qualifier、原理hotspot jvm 源码@Resource、注注解@Value
前言
在Spring框架中,解源@Autowired、原理@Qualifier、注注解@Resource、解源@Value四个注解常用于数据注入,原理类似于在xml配置文件中使用bean标签中的注注解property标签。
1、解源场景介绍
在使用@Autowired注解之前,原理我们先来看一个场景:在dao层、service层和controller层中,若没有正确注入AccountDao类,运行时会出现空指针异常。这是由于service层中的AccountDao属性未注入导致的。接下来,我们将使用@Autowired注解来解决这一问题。
2、@Autowired注解
Spring 2.5版本引入了@Autowired注解,用于自动装配类成员变量、方法、构造函数和参数。它主要应用于变量和方法,可以消除set和get方法,方便快捷。@Autowired注解的作用与在xml配置文件中的bean标签中使用property标签相同。
在Spring的IOC容器中,@Autowired注解会直接在容器中查找匹配的属性,与key无关。@Autowired自动装配的三种情况包括:1)容器中存在唯一匹配类型的bean对象;2)容器中不存在匹配类型的bean对象;3)容器中存在多个匹配类型的bean对象,则根据变量名进行注入。
3、@Qualifier注解
当容器中存在多个匹配类型的bean对象时,可以通过@Qualifier注解指定具体名称进行注入。@Qualifier注解通常与@Autowired一起使用,指明具体名称的自动装配。
4、@Resource注解
@Resource注解由J2EE提供,默认按照byName自动注入。它有两个重要属性:name和type,其中type属性通常不使用,因为它不如@Autowired灵活。@Resource注解主要用于通过名称自动注入。
5、103协议规约源码@Autowired与@Resource的区别
这两个注解非常相似,主要区别在于提供者和自动装配方式。@Autowired由Spring提供,而@Resource由J2EE提供。@Resource相当于@Autowired + @Qualifier。
6、@Value注解
@Value注解用于注入基本类型和String类型的数据。它有一个value属性,用于指定数据值,支持Spring的SpEL表达式。
7、小结
以上四个注解都用于注入数据,其作用类似于在xml配置文件中使用bean标签中的property标签。
@Autowired竟然能玩出这么多花样,涨见识了
最近在代码审查过程中,发现了@Autowired注解的多种不寻常用法,让我有了新的见解。现在分享这些研究发现,希望能对大家有所帮助。
也许@Autowired的强大超乎你的想象。
默认情况下,@Autowired用于自动装配对象。常规情况下,我们使用它如下:
当有多个相同类型的对象时,问题就出现了。按照默认的byType方式,这会导致冲突。
通过在测试目录下创建名为TestService1的类,重新启动项目时,会因类名冲突而导致项目无法启动。
注意,这种冲突不是因为自动装配的两个对象导致的,而是因为@Service方法不允许相同的类名,spring会将类名的第一个字母转换为小写作为bean名称,例如:testService1,且默认情况下bean名称必须唯一。
接下来,我们探讨如何创建两个相同的类型bean:
在TestConfig类中手动创建TestService1实例,并去掉TestService1类上的@Service注解。
重新启动项目,出现错误提示testService1是单例的,却找到了两个对象。
还有一种情况也会产生两个相同的类型bean:
重新启动项目,同样报错提示testService1是单例的,却找到了两个对象。
第二种情况在实际项目中更为常见。下面的例子将重点讨论这种情况。
通过使用@Qualifier和@Primary注解,ui控件库源码可以解决相同类型对象问题。
只需在代码上添加@Qualifier注解即可实现按名称装配:byName。
使用@Primary注解也能解决相同类型bean的问题,且无需使用@Qualifier注解。
当使用自动配置方式装配Bean时,如果存在多个候选者,其中具有@Primary注解修饰的候选者会被选中。
Autowired注解不仅限于成员变量使用,它还有更多强大用法。
例如,可以使用它在构造器、方法、参数和注解上,具体如下:
使用@Autowired注解在成员变量上装配。
在构造器上使用Autowired注解,实际上还是使用Autowired装配方式。
在普通方法和setter方法上使用Autowired注解,spring会在启动时自动调用,用于初始化工作。
在构造器的入参和非静态方法的入参上使用Autowired注解。
虽然使用了较多注解,但@Autowired也存在局限性,比如与特定框架的耦合性问题。此时,@Resource作为Java标准提供的选择,适用于更多框架。
在处理循环依赖问题时,@Autowired默认的单例机制通常能解决问题,但在某些情况下,需要特殊处理。
最后,@Autowired和@Resource的装配顺序不同。
虽然篇幅有限,但对@Autowired的深入理解将有助于更灵活地使用Spring框架。
@autowired注解有什么用?
最近在审查代码时,注意到一些@Autowired注解的非典型用法,觉得颇为有趣,于是花时间深入研究,发现了不少有价值的信息,现在与大家分享。 @Autowired可能比你想象的更为强大。1. 默认装配方式
我们知道,在Spring中,@Autowired注解主要用于自动装配对象。通常,我们在项目中这样使用: 是的,这样做确实能够实现装配,因为默认情况下,自然语音交流源码Spring会按照类型进行装配,即byType方式。 另外,@Autowired注解的required参数默认设为true,表示开启自动装配,若不希望使用自动装配功能,可通过将其设为false来实现。2. 相同类型的对象不止一个时
byType方式主要针对对象类型唯一的情况,当对象类型不唯一时,会出现问题。 例如,在项目的test目录下创建了一个名为TestService1的类。重启项目时,会报错,提示类名冲突,导致项目无法启动。 需要注意的是,这种情况与在@Autowired时出现两个相同类型的对象无关,容易引起混淆。问题是由于Spring的@Service方法不允许出现相同类名,而类名首字母转换为小写作为bean名称,如testService1,且默认情况下bean名称必须唯一。3. 使用@Qualifier和@Primary
显然,按照默认的byType装配方式,无法解决上述问题,此时可改用byName装配方式。 只需在代码中添加@Qualifier注解即可解决。 只需进行这样的调整,项目就能正常启动。 @Qualifier意味着“合格者”,通常与@Autowired结合使用,通过指定bean名称来找到需要装配的bean。 除了使用@Qualifier注解外,还可以使用@Primary注解解决相同类型bean的问题。在User1上加上@Primary注解,移除UserService上的@Qualifier注解。 重新启动项目,同样能正常运行。 当使用自动配置方式装配Bean时,若有多个候选者,其中一个带有@Primary注解,该候选者会被选中作为自动配置的值。4. @Autowired的使用范围
在成员变量上使用@Autowired注解是常见的用法。除此之外,它还能应用于其他场景。 下面总结一下@Autowired注解的使用方式:4.1 成员变量
在成员变量上使用@Autowired注解是常见用法。4.2 构造器
在构造器上使用@Autowired注解,溯源码直接扫描实际上还是使用了@Autowired装配方式,而非构造器装配。4.3 方法
在普通方法上添加@Autowired注解,spring会在项目启动时调用一次该方法,我们可在该方法中执行初始化工作。 同样可以在setter方法上使用@Autowired注解。4.4 参数
构造器的入参上可使用@Autowired注解,非静态方法的入参上也可使用。4.5 注解
使用@Autowired注解的注解实例相对较少,因此这里不再过多介绍。5. @Autowired的高级玩法
虽然上面的例子都是自动装配单个实例,但事实上,它也能自动装配多个实例。让我们看看是怎么实现的。 调整UserService方法,使用List集合接收IUser类型的参数。 增加一个controller,调用该接口。 通过观察结果,可以发现userList、userSet和userMap都打印出了两个元素,说明@Autowired会自动收集相同类型的IUser对象到集合中。 这种功能令人惊讶,令人惊喜!6. @Autowired装配是否一定成功?
前面介绍了@Autowired注解的强大功能,但有些情况下,即使使用了@Autowired仍然装配失败,这是为什么呢?6.1 没有加@Service注解
在类上忘记添加@Controller、@Service、@Component、@Repository等注解,Spring将无法完成自动装配功能,例如: 这种错误是最常见的,不会因为你长得帅,就避免犯这种低级错误。6.2 注入Filter或Listener
Web应用启动顺序为:listener->filter->servlet。 接下来我们看看这个案例: 程序启动会报错,提示tomcat无法正常启动。 原因是什么? 众所周知,springmvc的启动在DisptachServlet中完成,而它是在listener和filter之后执行。如果在listener和filter中使用@Autowired注入某个bean,肯定不行,因为filter初始化时,此时bean尚未初始化,无法自动装配。 如果在工作中真的需要这样做,该如何解决呢? 答案是使用WebApplicationContextUtils.getWebApplicationContext获取当前的ApplicationContext,再通过它获取bean实例。6.3 注解未被@ComponentScan扫描
通常情况下,@Controller、@Service、@Component、@Repository、@Configuration等注解需要通过@ComponentScan注解进行扫描,收集元数据。 但如果没有添加@ComponentScan注解,或其扫描路径错误或范围过小,可能导致注解收集不全,进而无法使用@Autowired完成自动装配。 好消息是,在springboot项目中,使用了@SpringBootApplication注解内置了@ComponentScan的功能。6.4 循环依赖问题
如果A依赖于B,B依赖于C,C又依赖于A,形成死循环。 Spring的bean默认是单例的,大多数情况下,能解决循环依赖问题。 但若bean是多例的,会引发循环依赖问题,导致自动装配失败。 还有些情况下,即使创建了代理对象,即使bean是单例的,也可能出现循环依赖问题。 如果你对循环依赖问题感兴趣,可以参考我的另一篇专题《》,其中详细介绍了相关内容。7. @Autowired与@Resource的区别
@Autowired功能强大,但也存在一些不足,比如它与Spring强耦合,换用其他框架功能失效。而@Resource是JSR-提供的,是Java标准,大部分框架都支持。 除此之外,在某些场景下,使用@Autowired无法满足需求,而使用@Resource则能解决问题。接下来,我们来看看@Autowired与@Resource的区别。 另外,它们的装配顺序不同。 @Autowired的装配顺序如下: @Resource的装配顺序如下:后记
原本计划接着分析@Autowired的原理和源码解读,但由于篇幅过长,不适合合并在一起,我打算另开一个专题。如果你对这个话题感兴趣,请持续关注我后续的文章,相信你一定能从中有所收获。注解@Autowired和@Resource的区别总结
@Autowired和@Resource是Spring框架中常见的依赖注入注解,但它们的注入机制和处理略有不同。接下来,我们将从源码角度深入剖析它们的注入过程。
@Autowired总结:
- 注入流程涉及AutowiredAnnotationBeanPostProcessor,首先检查属性或方法上的@Autowired,构建AutowiredFieldElement或AutowiredMethodElement。
- 如果未启用懒加载,AutowiredFieldElement会通过DefaultListableBeanFactory的resolveDependency方法寻找并注入bean,包括候选bean的查找和确定。
@Resource总结:
- CommonAnnotationBeanPostProcessor的buildResourceMetadata方法是切入点,只对非静态、非忽略类型的字段创建ResourceElement对象。
- ResourceElement对象的getResourceToInject方法负责获取bean,通过autowireResource方法调用。
源码分析:
1. @Autowired的注入过程涉及AutowiredAnnotationBeanPostProcessor的多个内部方法,如doResolveDependency和findAutowireCandidates,处理了候选bean的选择和懒加载机制。
2. @Resource的流程在CommonAnnotationBeanPostProcessor中更为直接,主要通过ResourceElement类的getResourceToInject方法获取bean。
学习更多关于Java和Spring的深入知识,如MyBatis、ZooKeeper等,持续关注博主的更新。
Spring源码Autowired注入流程
在Spring框架中,Autowired注解的注入流程是一个开发者常问的问题。本文将带你深入了解这一过程,基于jdk1.8和spring5.2.8.RELEASE环境。
首先,当Spring应用启动,通过SpringApplication的run方法调用refreshContext,进而执行refresh方法,初始化上下文容器。在这个过程中,非懒加载的bean实例化由finishBeanFactoryInitialization方法负责,特别是其内部的beanFactory.preInstantiateSingletons方法。
在默认非单例bean的getBean方法中,会调用AbstractAutowireCapableBeanFactory的createBean方法,这个方法会处理包括@Autowired在内的各种注解。特别关注AutowiredAnnotationBeanPostProcessor,它在获取元数据后,会进入beanFactory.resolveDependency来处理可能的多个依赖问题。
最后,DefaultListableBeanFactory的doResolveDependency方法通过反射机制,实现了属性注入。尽管这只是整个流程的概述,但深入源码可以帮助我们更好地理解Autowired的底层工作机制。
虽然这只是一个基本的梳理,但希望能为理解Spring的Autowired注入提供一些帮助。写这篇文章我投入了一周的时间,尽管过程艰辛,但如果觉得有价值,请给予鼓励,如点赞、收藏或转发。期待您的宝贵意见,让我们共同进步!
autowired和resource注解的区别
autowired和resource注解的区别 @Autowired和@Resource注解都是用于实现依赖注入的,但是他们在来源、使用范围和注入方式上存在区别。 @Autowired是Spring框架提供的注解,它按照类型(byType)进行自动装配,如果同一个类型的Bean有多个,则可能会抛出异常。@Autowired常用于依赖关系的建立,特别是在处理服务层和DAO层的时候。 @Resource是Java的内置注解,来源于JSR-规范,它默认按照名称(byName)进行自动装配。如果需要注入的Bean没有指定名称,则会按照类型(byType)进行自动装配。如果同一个类型的Bean有多个,而没有指定名称,则可能会抛出异常。 总结来说,@Autowired和@Resource在来源、使用范围和注入方式上有所不同。选择哪种注解取决于项目需要和设计考虑。Spring中@Autowired和@Resource的区别
近期,众多应届毕业生纷纷进入职场,招聘竞争愈发激烈。无论是应届生还是中高级人才,面试时往往都会被问到技术原理问题,甚至是一些在日常开发中不太常见的知识点对比。今天,我要分享一道在面试中经常出现的问题:在Spring框架中,@Autowired注解和@Resource注解的区别。
此外,我还花费了超过一周的时间整理了往期面试题的解析文档,想要获取这些资料的小伙伴可以在我的个人简介中找到。
首先,我们来了解一下@Autowired注解。
@Autowired注解由Spring提供,可以用来标注构造方法、成员变量和方法参数,实现对象类型的自动注入。例如:
public class Service { //构造方法注入 @Autowired public Service(Service service) { this.service = service; } //成员变量注入 @Autowired private Service service; //方法参数注入 @Autowired public void setService(Service service) { this.service = service; } }
接下来,我们来看看@Resource注解。
@Resource注解由JDK提供,遵循JSR-规范,是Java 1.6及以上版本的新特性。作为Java的标准,其作用与@Autowired类似。与@Autowired不同的是,@Resource可以适用于所有Java框架,而@Autowired仅适用于Spring。简单来说,@Resource可以支持对象类型注入和对象名称注入。
那么,@Resource和@Autowired之间具体有哪些区别呢?以下从五个方面进行分析:
1)注解内部定义的参数不同:@Autowired只包含一个required参数,默认为true,表示开启自动注入;而@Resource包含七个参数,其中最重要的是name和type。
2)装配方式的默认值不同:@Autowired默认按type自动装配,而@Resource默认按name自动装配。当然,@Resource注解可以自定义选择,如果指定了name,则根据name自动装配,如果指定了type,则用type自动装配。
3)注解应用的范围不同:@Autowired可以用于构造方法、成员变量、方法参数和注解上,而@Resource可以用于类、成员变量和方法参数。
4)出处不同:@Autowired是Spring定义的注解,而@Resource遵循JSR-规范,定义在JDK中。因此,@Autowired只能在Spring框架下使用,而@Resource可以与其他框架一起使用。
5)装配顺序不同:@Autowired默认先按byType进行匹配,如果发现找到多个bean,则按照byName方式进行匹配,如果还有多个,则报出异常。而@Resource的装载顺序分为四种情况:
1)如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常;
2)如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常;
3)如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常;
4)如果既没有指定name,也没有指定type,则自动按byName方式进行装配。如果没有匹配,则回退为按照类型进行匹配。
为了帮助大家更好地理解和区分,我还专门整理了一张表格。有需要的小伙伴可以关注我的主页介绍。
以上就是对@Autowired与@Resource的总结和理解。总结一下,两者在功能上差别不大,使用起来也差不多。但在日常开发中,我建议使用@Autowired,以下是我的三个理由:
1)@Autowired功能略强大,支持优先注入、可以配置允许bean不存在;
2)若使用了Spring框架,使用其特有的注解个人感觉更好一点;
3)有人认为@Resource更加通用,因为它是个规范,其他框架也会支持。但我认为,目前后端都是在用Spring了,没有必要考虑其他框架。
当然,这个跟我个人是Spring迷无关哈,如果你也是Spring的小迷粉,可以关注我,一起交流,共同进步。
我是被编程耽误的文艺Tom,如果你还有其他不懂的面试题或者需要视频配套的文字资料,可以关注我的主页介绍。如果我的面试解析对你有帮助,请动动手指一键三连分享给更多的人。关注我,面试不再难!
关注微信公众号Tom弹架构领取完整版万字面试资料和答案吧,以及页PDF文档!