文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring中@Autowired、@Resource和@Inject注解的区别是什么

2023-07-05 09:35

关注

这篇文章主要介绍了Spring中@Autowired、@Resource和@Inject注解的区别是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring中@Autowired、@Resource和@Inject注解的区别是什么文章都会有所收获,下面我们一起来看看吧。

javax.annotation.Resource

jdk 内置的,JSR-250 中的注解。

依赖注入通过 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor 来处理。

org.springframework.beans.factory.annotation.Autowiredorg.springframework.beans.factory.annotation.Value
javax.inject.Inject

JSR-330 中的注解,作用同 @Autowired

依赖注入通过 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor 来处理。

org.springframework.beans.factory.annotation.Qualifierjavax.inject.Qualifier

依赖注入通过 org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver 来处理。

@Autowired

spring 自带的注解。

注入顺序

按照 type 在 上下文中查找匹配的 bean

如果有多个 bean,按照 name 进行匹配

匹配不到,报错。因为 required 默认为 true,不想注入设置此 bean @Autowired(required=false)。

@Inject

在 spring 中,@Inject 和 @Autowired 相同。

@Inject 和 @Autowired 区别

@Inject 是 javaee 6 及以上版本包里的。

@Autowired 可以设置 required=false 而 @Inject 没有这个属性。

@Resource

有两个重要的属性,name 和 type,spring 将 name 属性解析为 bean 的名字,type 解析为 bean 的类型。如果未指定 name,取变量名给 name 赋值。

CommonAnnotationBeanPostProcessor 中Resource 赋值源码

    private class ResourceElement extends LookupElement {        private final boolean lazyLookup;        public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {            super(member, pd);            Resource resource = ae.getAnnotation(Resource.class);            String resourceName = resource.name();            Class<?> resourceType = resource.type();            this.isDefaultName = !StringUtils.hasLength(resourceName);            if (this.isDefaultName) {                resourceName = this.member.getName();                if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {                    resourceName = Introspector.decapitalize(resourceName.substring(3));                }            }            else if (embeddedValueResolver != null) {                resourceName = embeddedValueResolver.resolveStringValue(resourceName);            }            if (Object.class != resourceType) {                checkResourceType(resourceType);            }            else {                // No resource type specified... check field/method.                resourceType = getResourceType();            }            this.name = (resourceName != null ? resourceName : "");            this.lookupType = resourceType;            String lookupValue = resource.lookup();            this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());            Lazy lazy = ae.getAnnotation(Lazy.class);            this.lazyLookup = (lazy != null && lazy.value());        }        @Override        protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {            return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :                    getResource(this, requestingBeanName));        }    }

在变量名相同的情况下报错

The bean could not be injected as a because it is a JDK dynamic proxy that implements:

指定了不同type无法解决问题,跟进源码发现是 spring boot 把异常给处理了

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'productInit': 
Injection of resource dependencies failed; 
nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: 
Bean named 'example2ProductMapper' is expected to be of type 'com.alibaba.cloud.youxia.manager.ProductManager' but was actually of type 'com.sun.proxy.$Proxy47'

想到在 DefaultListableBeanFactory 中 beanDefinitionMap 按照名称和 BeanDefinition 键值对的问题,名称和注入的对象一一对应,不然就会出现不对应的问题

注入规则

通过变量名从上下文中查找不到对应的 bean,则通过 type则从上下文中查找类型匹配的 bean 进行注入,找不到抛出异常。

通过变量名从上下文中找到对应的 bean但是注入的类型与无法与DefaultListableBeanFactory 中 beanDefinitionMap中通过变量名得到的 BeanDefinition 类型一致,抛出异常。

匹配顺序为

变量名 &rarr; 指定的 name &rarr; 指定的 type

Spring中@Autowired、@Resource和@Inject注解的区别是什么

如果注入的 bean 变量名相同,但是类型不同,通过 name 指定是修改代码量最小的办法。

Spring中@Autowired、@Resource和@Inject注解的区别是什么

关于“Spring中@Autowired、@Resource和@Inject注解的区别是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Spring中@Autowired、@Resource和@Inject注解的区别是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯