详解JavaSpring各种依赖注入注解的区别Word文档下载推荐.docx
- 文档编号:3114154
- 上传时间:2023-05-01
- 格式:DOCX
- 页数:15
- 大小:21.57KB
详解JavaSpring各种依赖注入注解的区别Word文档下载推荐.docx
《详解JavaSpring各种依赖注入注解的区别Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《详解JavaSpring各种依赖注入注解的区别Word文档下载推荐.docx(15页珍藏版)》请在冰点文库上搜索。
@Autowired和@Inject-默认autowiredbytype-可以通过@Qualifier显式指定autowiredbyqualifiername。
-如果autowiredbytype失败(找不到或者找到多个实现),则退化为autowiredbyfieldname@Resource-默认autowiredbyfieldname-如果autowiredbyfieldname失败,会退化为autowiredbytype-可以通过@Qualifier显式指定autowiredbyqualifiername-如果autowiredbyqualifiername失败,会退化为autowiredbyfieldname。
但是这时候如果autowiredbyfieldname失败,就不会再退化为autowiredbytype了。
TIPSQualifiednameVSBeanname
在Spring设计中,Qualifiedname并不等同于Beanname,后者必须是唯一的,但是前者类似于tag或者group的作用,对特定的bean进行分类。
可以达到getByTag(group)的效果。
对于XML配置的bean,可以通过id属性指定beanname(如果没有指定,默认使用类名首字母小写),通过标签指定qualifiername:
1234
<
beanid="
lamborghini"
class="
me.arganzheng.study.spring.autowired.Lamborghini"
>
<
qualifiervalue="
luxury"
/>
!
--injectanydependenciesrequiredbythisbean-->
/bean>
如果是通过注解方式,那么可以通过@Qualifier注解指定qualifiername,通过@Named或者@Component(@Service,@Repository等)的value值指定beanname:
@Component("
)@Qualifier("
)publicclassLamborghiniimplementsCar{}
或者
12345
@Component@Named("
同样,如果没有指定beanname,那么Spring会默认是用类名首字母小写(Lamborghini=>
lamborghini)。
三、通过Anotation注入依赖的方式在XML注入方式之前进行。
如果对同一个bean的依赖同时使用了两种注入方式,那么XML的优先。
但是不同担心通过Anotation注入的依赖没法注入XML中配置的bean,依赖注入是在bean的注册之后进行的。
四、目前的autowiredbytype方式(笔者用的是3.2.3.RELEASE版本),Spring的AutowiredAnnotationBeanPostProcessor实现都是有”bug”的,也就是说@Autowired和@Inject都是有坑的(称之为坑,不称之为bug是因为貌似是故意的。
。
)。
这是来源于线上的一个bug,也是这边文章的写作原因。
现场如下:
application-context.xml中有如下定义:
12345678910111213141516171819202122232425262728293031323334353637383940414243
xmlversion="
1.0"
encoding="
UTF-8"
?
beansxmlns="
http:
//www.springframework.org/schema/beans"
xmlns:
xsi="
//www.w3.org/2001/XMLSchema-instance"
xmlns:
aop="
//www.springframework.org/schema/aop"
context="
//www.springframework.org/schema/context"
util="
//www.springframework.org/schema/util"
xsi:
schemaLocation="
http:
//www.springframework.org/schema/beanshttp:
//www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp:
//www.springframework.org/schema/aophttp:
//www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp:
//www.springframework.org/schema/contexthttp:
//www.springframework.org/schema/context/spring-context-3.0.xsdhttp:
//www.springframework.org/schema/utilhttp:
//www.springframework.org/schema/util/spring-util-2.5.xsd"
context:
annotation-config/>
component-scanbase-package="
me.arganzheng.study"
/>
util:
constantid="
en"
static-field="
me.arganzheng.study.spring.autowired.Constants.Language.EN"
ja"
me.arganzheng.study.spring.autowired.Constants.Language.JP"
ind"
me.arganzheng.study.spring.autowired.Constants.Language.IND"
pt"
me.arganzheng.study.spring.autowired.Constants.Language.PT"
th"
me.arganzheng.study.spring.autowired.Constants.Language.TH"
ar"
me.arganzheng.study.spring.autowired.Constants.Language.AR"
en-rIn"
me.arganzheng.study.spring.autowired.Constants.Language.EN_RIN"
mapid="
languageChangesMap"
key-type="
java.lang.String"
value-type="
entrykey="
value="
br"
jp"
id"
en-rin"
in"
gb"
eg"
/util:
map>
/beans>
其中static-field应用的常量定义在如下类中:
123456789101112
packageme.arganzheng.study.spring.autowired;
publicinterfaceConstants{publicinterfaceLanguage{publicstaticfinalStringEN="
CommonConstants.LANG_ENGLISH"
;
publicstaticfinalStringJP="
CommonConstants.LANG_JAPANESE"
publicstaticfinalStringIND="
CommonConstants.LANG_INDONESIAN"
publicstaticfinalStringPT="
CommonConstants.LANG_PORTUGUESE"
publicstaticfinalStringTH="
CommonConstants.LANG_THAI"
publicstaticfinalStringEN_RIN="
CommonConstants.LANG_ENGLISH_INDIA"
publicstaticfinalStringAR="
CommonConstants.LANG_Arabic"
}}
然后如果我们在代码中如下声明依赖:
12345678910
publicclassAutowiredTestextendsBaseSpringTestCase{@AutowiredprivateMap<
String,String>
languageChangesMap;
@TestpublicvoidtestAutowired(){notNull(languageChangesMap);
System.out.println(languageChangesMap.getClass().getSimpleName());
System.out.println(languageChangesMap);
Guesswhat,诡异的事情发生了!
运行结果如下:
12
LinkedHashMap{en=CommonConstants.LANG_ENGLISH,ja=CommonConstants.LANG_JAPANESE,ind=CommonConstants.LANG_INDONESIAN,pt=CommonConstants.LANG_PORTUGUESE,th=CommonConstants.LANG_THAI,ar=CommonConstants.LANG_Arabic,en-rIn=CommonConstants.LANG_ENGLISH_INDIA}
也就是说Map
严重:
CaughtexceptionwhileallowingTestExecutionListener
[org.springframework.test.context.support.DependencyInjectionTestExecutionListener@5c51ee0a]topreparetestinstance[me.arganzheng.study.spring.autowired.AutowiredTest@6e301e0]org.springframework.beans.factory.BeanCreationException:
Errorcreatingbeanwithname'
me.arganzheng.study.spring.autowired.AutowiredTest'
:
Injectionofautowireddependenciesfailed;
nestedexceptionisorg.springframework.beans.factory.BeanCreationException:
Couldnotautowirefield:
privatejava.util.Mapme.arganzheng.study.spring.autowired.AutowiredTest.languageChangesMap;
nestedexceptionisorg.springframework.beans.factory.NoSuchBeanDefinitionException:
Noqualifyingbeanoftype[java.lang.String]foundfordependency[mapwithvaluetypejava.lang.String]:
expectedatleast1beanwhichqualifiesasautowirecandidateforthisdependency.Dependencyannotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}...edby:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}atorg.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:
986)atorg.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:
843)atorg.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:
768)atorg.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:
486)...28more
debug了一下,发现确实是Spring的一个bug。
在DefaultListableBeanFactory的这个方法出问题了:
123456789101112131415161718192021222324252627282930313233
protectedObjectdoResolveDependency(DependencyDescriptordescriptor,Class<
type,StringbeanName,Set<
String>
autowiredBeanNames,TypeConvertertypeConverter)throwsBeansException{...elseif(Map.class.isAssignableFrom(type)&
&
type.isInterface()){Class<
keyType=descriptor.getMapKeyType();
if(keyType==null||!
String.class.isAssignableFrom(keyType)){if(descriptor.isRequired()){thrownewFatalBeanException("
Keytype["
+keyType+"
]ofmap["
+type.getName()+"
]mustbeassignableto[java.lang.String]"
);
}returnnull;
}Class<
valueType=descriptor.getMapValueType();
if(valueType==null){if(descriptor.isRequired()){thrownewFatalBeanException("
Novaluetypedeclaredformap["
]"
}Map<
String,Object>
matchingBeans=findAutowireCandidates(beanName,valueType,descriptor);
if(matchingBeans.isEmpty()){if(descriptor.isRequired()){raiseNoSuchBeanDefinitionException(valueType,"
mapwithvaluetype"
+valueType.getName(),descriptor);
}if(autowiredBeanNames!
=null){autowiredBeanNames.addAll(matchingBeans.keySet());
}returnmatchingBeans;
}...}
关键在这一句:
Map
12345678
[org.springframework.test.context.support.DependencyInjectionTestExecutionListener@9476189]topreparetestinstance[zheng.study.spring.autowired.AutowiredTest@2d546e21]...Causedby:
{@org.springframework.beans.factory.annotation.Autowired(required=true),@org.springframework.be
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 详解 JavaSpring 各种 依赖 注入 注解 区别
![提示](https://static.bingdoc.com/images/bang_tan.gif)