Spring中@Autowired、@Resource和@Inject注解的区别是什么(@autowired,@resource,spring,开发技术)

时间:2024-05-06 11:51:11 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :
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 进行匹配

  • 如果有 @Qualifier 注解,按照 @Qualifier 指定的 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 赋值源码

/***Classrepresentinginjectioninformationaboutanannotatedfield*orsettermethod,supportingthe@Resourceannotation.*/privateclassResourceElementextendsLookupElement{privatefinalbooleanlazyLookup;publicResourceElement(Membermember,AnnotatedElementae,@NullablePropertyDescriptorpd){super(member,pd);Resourceresource=ae.getAnnotation(Resource.class);StringresourceName=resource.name();Class<?>resourceType=resource.type();this.isDefaultName=!StringUtils.hasLength(resourceName);if(this.isDefaultName){resourceName=this.member.getName();if(this.memberinstanceofMethod&&resourceName.startsWith("set")&&resourceName.length()>3){resourceName=Introspector.decapitalize(resourceName.substring(3));}}elseif(embeddedValueResolver!=null){resourceName=embeddedValueResolver.resolveStringValue(resourceName);}if(Object.class!=resourceType){checkResourceType(resourceType);}else{//Noresourcetypespecified...checkfield/method.resourceType=getResourceType();}this.name=(resourceName!=null?resourceName:"");this.lookupType=resourceType;StringlookupValue=resource.lookup();this.mappedName=(StringUtils.hasLength(lookupValue)?lookupValue:resource.mappedName());Lazylazy=ae.getAnnotation(Lazy.class);this.lazyLookup=(lazy!=null&&lazy.value());}@OverrideprotectedObjectgetResourceToInject(Objecttarget,@NullableStringrequestingBeanName){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 键值对的问题,名称和注入的对象一一对应,不然就会出现不对应的问题

注入规则

  • 如果未指定 name,取变量名从上下文中查找名称匹配的 bean 进行注入,找不到或者注入的变量名与类型无法对应抛出异常。

  • 如果指定了 name,则从上下文中查找名称匹配的 bean 进行注入,找不到抛出异常。

  • 如果指定了 type,有两种情况

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

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

  • 既没有指定 name,又没有指定 type,默认按照变量名进行注入。

  • 如果同时指定了 name 和 type,从上下文中找到唯一匹配的 bean 进行注入,找不到抛出异常。

匹配顺序为

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

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

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

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

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Spring中@Autowired、@Resource和@Inject注解的区别是什么的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:OPENMP SECTIONS CONSTRUCT原理是什么下一篇:

2 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18