注入2.4 IoC容器的依赖注入(5).

依赖注入  时间:2021-02-08  阅读:()

代码清单2-301.private vo id setPropertyValue(PropertyTokenHo lder tokens,

2.PropertyValue pv) throws BeansException{String

3.propertyName=tokens.canonicalName;S tring actualName=

4. tokens.actualName; if(tokens.keys !=null) { //App ly

5. indexes and map keys:fetch value for all keys but the last

6.one.PropertyTokenHo lder getterTokens=new

7.PropertyTokenHo lder();getterTokens.cano nicalName=

8. tokens.cano nicalName;getterTokens.actualName=

9. tokens.actualName;getterTokens.keys=new

10.String[tokens.keys.length- 1];

11.Sys tem.arraycop y(tokens.keys,0,getterTokens.keys,0,

12. tokens.keys. length- 1);Obje ct propValue;

13. //getP ropertyValue取得bean中注入对象的引用 比如Array、 List

14. 、Map、 Set等。 try{propValue=

15.ge tPropertyVa lue(ge tte rTok e ns); } catc h

16. (NotReadablePropertyException ex) { throw new

17.NotWritab lePropertyException(getRootC lass(), this.nested

18.Path+propertyName, "Cannot access indexed value in

19.property referenced"+"in indexed property path'"+

20.propertyName+"'", ex); } //Set value for last key.

21.String key=tokens.keys[tokens.keys.length- 1]; if

22. (propValue==null) { throw new

23.NullValueInNestedPathException(getRootC las s(), this.ne sted

24.Path+propertyName, "Cannot access indexed value in

25.property referenced"+"in indexed property path'"+

26.propertyName+"' :returned null"); }

27. //这里对Array进行注入。 else if

28. (propValue.getC lass().isArray()) {C lass requiredType=

29.propValue.getC la ss().getCo mpo nentType(); int arrayInde x=

30. Inte ger.parseInt(key);Object o ldValue=null; try{

31. if(is Extra ctO ldVa lueForEd ito r()) {o ldVa lue=

32.Array.ge t(p ropVa lue,arrayInde x); }Obj ect

33.convertedValue=this.typeCo nverterDe le gate.

34.convertI fNec essary(propertyName,o ldValue,p v.getValue(),

35.required Type);Array.set(p ropVa lue,

36. Inte ger.p a rs eI nt(ke y),c o nvertedVa lue); } c atc h

37. (IllegalArgumentException ex) {Prop ertyChangeEvent pce

38.=new

39.PropertyC hangeEvent(this.rootObject,this.nestedPath+

40.propertyName,o ldValue,p v.ge tValue()); thro w new

41.TypeM ismatchExceptio n(pce, requiredTyp e,e x); } catch

42. (IllegalStateException ex) {PropertyChangeEvent pce=

43.new PropertyChangeEvent(this.rootObject,this.nestedPath

44.+propertyName,o ldValue,p v.getValue()); thro w new

45.Convers ionNotS upportedException(pce,requiredType,ex); }

46.catch(IndexOutOfBoundsException ex) { throw new

47. Inva lidP ropertyExcep tio n(getRootC lass(),this.nes tedPath+

48.propertyName,"Invalid array index in property path'"+

49.propertyName+"'", ex); } } //这里对List进行注入。

50.else if(propValue instanceof List) {PropertyDescriptor

51.pd=getCachedIntrospectio nResults().getP ropertyDes crip tor

52. (actualName);C lass requiredType=

53.GenericCo llectionTypeReso lver.getCo llectionReturnType(

54.pd.getReadMethod(), tokens.keys.length);List list=

55. (List)propValue; int index=Inte ger.p arse Int(key);

56.Obj ect o ldVa lue=null; if(isExtrac tO ldVa lueForEd itor()

57.&&index<list.s ize()) {o ldValue=list.get(index);

58. } try{Object convertedValue=

59. this.typeConverterDe le gate.convertI f Neces sary(

60.propertyName,o ldVa lue,p v.ge tVa lue(),required Type); if

61. (index<list.s ize()) { list.set(index,

62.convertedValue); } else if(index>=list.size()) {

63.for(int i=list.size(); i<index; i++) { try{

64. lis t.add(null); } catc h(N ullPo interExcep tio n e x) {

65. throw new InvalidP ropertyExcep tio n(getRootC lass(),

66. this.nestedPath+propertyName, "Cannot set element

67.with index"+index+" in List of size "+

68. list.size()+",accessed using property path'"+

69.propertyName+"' :List does not support filling up

70.gaps with null elements"); } }

71. lis t.add(co nve rted Va lue); } } catc h

72. (IllegalArgumentException ex) {Prop ertyChangeEvent pce=

73.new PropertyChangeEvent(this.rootObje ct,this.nestedPath

74.+propertyName,o ldValue,p v.getValue()); thro w new

75.TypeM ismatchExceptio n(pce, requiredTyp e,ex); } }

76. //里对Map进行注入。 else if(propValue instanceofMap) {

77.PropertyDescriptor pd=

78.getCachedIntrospectionResults().getP ropertyDes crip tor(actual

79.Name);Class mapKeyType=

80.GenericCollectionTypeResolver.getMapKeyReturnType(

81.pd.getReadMethod(), tokens.keys.length);C las s

82.mapValue Type=

83.GenericCollectionTypeResolver.getMapValueReturnType(

84.pd.getReadMethod(), tokens.keys.length);Map map=(Map)

85.propValue;Object convertedMapKey;Object

86.convertedMapValue; try{ /** *IMPORTANT:Do not

87.pass full property name in here-property editors*

88.must not kick in for map keys but rather only for map

89.values. */convertedMapKey=

90. this.typeConverterDe le gate.convertI fNeces sary(key,

91.mapKeyType); } catch(Ille galArgumentExcep tion ex) {

92.PropertyChangeEvent pce=new

93.PropertyC hangeEvent(this.rootObject, this.nestedPath+

94.propertyName,null,p v.ge tValue()); thro w ne w

95.TypeMismatchException(pce,mapKeyType, ex); }Object

96.oldVa lue=null; if(is ExtractO ldVa lueFo rEd ito r()) {

97.oldValue=map.get(convertedMapKey); } try{ /**

98. *Pass full property name and old value in here, since we

99.want full*convers ion ab ility for map value s. */ 100.convertedM apValue=

101. this.typeConverterDe le gate.convertIfNeces sary(

102.propertyName,o ldVa lue,p v.ge tVa lue(),map Va lue Type,null, 103.ne wMethodParamete r(pd.getReadMethod(), -1, tokens. 104.keys.length+1)); } catc h(IllegalArgumentException 105.ex) {PropertyChangeEvent pce=new

106.PropertyC hangeEvent(this.rootObject, this.nested Path+

107.propertyName,o ldValue,p v.ge tValue()); thro w new

108.TypeMismatchException(pce,mapValue Type,ex); }

109.map.put(convertedMapKey, convertedMapValue); } els e { 110. throw newInva lidP ropertyExcep tio n(getRootC lass(),

111. this.nestedPath+propertyName, "Property re ferenced 112. in indexed propertypath'"+propertyName+"' is

113.neither an array nor a List nor a Map;returned value was [" 114.+pv.getValue()+"]"); } }//这里对非集合类的域进行注入。

115.else {PropertyDe scriptor pd=pv.reso lvedDes criptor; if 116. (pd==null| |

117. !pd.getWriteMethod().getDec laringC lass().isInstance

118. (this.object)) {pd=

119.getCachedIntrospectionResults().getP ropertyDes criptor(actual 120.Name); if(pd==null | |pd.ge tWrite Method()==null) { 121.Prope rtyMatc hes matc he s

122.=PropertyM atches.forProperty(propertyName,

123.getRootC lass()); throw new NotWritab lePropertyException( 124.getRootC las s(),this.nestedPath+propertyName,

125.matc hes.b uildErrorMe ssa ge(),matc hes.ge tPo ss ib leM atc hes()); 126. }pv.getOriginalPropertyValue().re so lvedDescripto r=pd; 127. }Object o ldValue=null;try{Object originalValue 128.=pv.getValue();Object valueToApply=originalValue;

129. if(!Boolean.FALSE.equals(pv.conversionNecessary)) { if 130. (pv.isConverted()){va lue To App ly=

131.pv.ge tC onve rtedVa lue(); } e lse { if

132. (is ExtractO ldVa lueFo rEd ito r()&&pd.ge tReadMe thod() !=null) 133. {MethodreadMethod=pd.getReadMethod(); if

134. (!Modifier.isPub lic(readMethod.getDec laringC lass().

135.getModifiers())) {readM ethod.setAccess ib le(true); } 136. try{o ldValue=readMethod.invoke(this.object); 137. } catch(Exception ex) { if

138. (logger.isDebugEnabled()) { logger.debug("Could not 139. read previous value ofproperty'"+

140. this.nestedPath+propertyName+"'",ex); } } 141. }valueToApp ly=

142. this.typeConverterDe le gate.convertIfNeces sary

143. (o ldValue,originalValue,pd); }

144.pv.getOriginalPrope rtyValue().co nvers io nNeces sary=

145. (value ToApp ly!=originalValue); }

146. //这里取得注入属性的set方法通过反射机制把对象注入进去。

147.Method writeMethod=pd.getWriteMethod(); if

148. (!Modifier.isPublic(writeMethod.getDeclaringC lass().getModif 149. iers())){writeMethod.setAccessib le(true); }

150.writeMethod.invoke(this.object,valueToApp ly); } catch

151. (InvocationTargetExc eption ex) {PropertyChangeEvent

152.propertyC hangeEvent=new

153.PropertyC hangeEvent(this.rootObject, this.nestedPath+

154.propertyName,o ldValue,p v.getValue()); if

155. (ex.getTargetException() instanceof C lassCastException) {

156.pd.getPropertyTyp e(),ex.getTargetException()); } else

157. { throw new

158.MethodInvocationException(propertyChangeEvent,

159.ex.ge tT argetExcep tio n()); } } catc h

160. (IllegalArgumentException ex) {Prop ertyChangeEvent pce=161.new

PropertyC hangeEvent(this.roo tObject, this.nestedPath+162.propertyName,o ldValue,pv.getValue()); thro w new

163.TypeMismatchException(pce,pd.getPropertyType(),ex); }

164.catch(Ille galState Exceptio n ex) {PropertyC hange Event

165.pce=new PropertyChangeEvent(this.rootObject,

166. this.nestedPath+propertyName,o ldValue, 167.p v.getValue()); throw new

168.ConversionNotS upportedException(pce,pd.getPropertyType(),

169.ex); } catch(IllegalAcce ssException ex) {

170.PropertyChangeEvent pce=new

171.PropertyC hangeEvent(this.rootObject, this.nestedPath+

172.propertyName,o ldValue,p v.ge tValue()); thro w new

173.MethodInvocationException(pce,ex); } }}

这样就完成了对各种bean属性的依赖注入过程。笔者以前探寻过Spring 2.0的源代码在这里发现Spring 3.0的源代码已经有了很大的改进整个过程更为清晰了特别是关于依赖注入的这一部分。如果读者有兴趣可以分别研究并比较一下Spring 2.0和Spring 3.0对这部分的实现这样可以更清晰地看到Spring源代码的演进过程也可以看到Spring团队对代码进行重构的思路。

在Bean的创建和对象依赖注入的过程中需要依据BeanDe finition中的信息来递归地完成依赖注入。从上面可以看到几个递归过程这些递归都是以getBean为入口的。一个是在上下文体系中查找需要的Bean和创建Bean的递归调用另一个递归在依赖注入时通过递归调用容器的getBean方法得到当前Bean的依赖Bean 同时也触发对依赖Bean的创建和注入。在对Bean的属性进行依赖注入

时解析的过程也是一个递归的过程。这样根据依赖关系一层一层地完成Bean的创建和注入直到最后完成当前Bean的创建有了这个顶层Bean的创建和对它的属性依赖注入的完成也意味着和当前Bean相关的整个依赖链的注入完成。

在Bean建立和依赖注入完成以后在IoC容器中建立起一系列靠依赖关系联系起来的Bean这个Bean已经不是简单的Java对象了。这个Bean系列建立完成以后通过IoC容器的相关接口方法就可以非常方便地让上层应用使用了。回到前面的关于水桶的例子到这里我们不但找到了水源而且成功地把水装到了水桶中 同时对水桶里的水完成了一系列的处理 比如消毒、煮沸……尽管还是水但经过一系列的处理以后这些水已经是开水了 已经可以直接饮用了

RAKsmart:美国洛杉矶独服,E3处理器/16G/1TB,$76.77/月;美国/香港/日本/韩国站群服务器,自带5+253个IPv4

RAKsmart怎么样?RAKsmart机房即日起开始针对洛杉矶机房的独立服务器进行特别促销活动:低至$76.77/月,最低100Mbps带宽,最高10Gbps带宽,优化线路,不限制流量,具体包括有:常规服务器、站群服务器、10G大带宽服务器、整机机柜托管。活动截止6月30日结束。RAKsmart,美国华人老牌机房,专注于圣何塞服务器,有VPS、独立服务器等。支持PayPal、支付宝付款。点击直达...

bgpto:独立服务器夏季促销,日本机器6.5折、新加坡7.5折,20M带宽,低至$93/月

bgp.to对日本机房、新加坡机房的独立服务器在搞特价促销,日本独立服务器低至6.5折优惠,新加坡独立服务器低至7.5折优惠,所有优惠都是循环的,终身不涨价。服务器不限制流量,支持升级带宽,免费支持Linux和Windows server中文版(还包括Windows 10). 特色:自动部署,无需人工干预,用户可以在后台自己重装系统、重启、关机等操作!官方网站:https://www.bgp.to...

搬瓦工:香港PCCW机房即将关闭;可免费升级至香港CN2 GIA;2核2G/1Gbps大带宽高端线路,89美元/年

搬瓦工怎么样?这几天收到搬瓦工发来的邮件,告知香港pccw机房(HKHK_1)即将关闭,这也不算是什么出乎意料的事情,反而他不关闭我倒觉得奇怪。因为目前搬瓦工香港cn2 GIA 机房和香港pccw机房价格、配置都一样,可以互相迁移,但是不管是速度还是延迟还是丢包率,搬瓦工香港PCCW机房都比不上香港cn2 gia 机房,所以不知道香港 PCCW 机房存在还有什么意义?关闭也是理所当然的事情。点击进...

依赖注入为你推荐
刷网站权重如何刷流量才能提高网站权重天府热线劲舞团(四川天府热线)为什么越来越卡了??万网核心代理我想买个域名和空间,我一朋友给我介绍万网代理环宇网络空间商,他们的空间稳定吗,价格怎么样,咨询师的服天天酷跑刷金币天天酷跑如何刷分刷金币?安装迅雷看看播放器如何用手机安装迅雷看看播放器2012年正月十五农历2012年正月15早上9点多生的!命里缺什么!是什么命相iphone6上市时间苹果6什么时候在中国大陆上市网页打开很慢为什么我打开浏览器的时候,网页打开的很慢?云挂机快手极速版后台云挂机辅?助各位用了吗?在哪找的?服务器连接异常主服务器连接异常
国际域名 如何注销域名备案 冰山互联 hawkhost vpsio rackspace 免费个人博客 美国十次啦服务器 ntfs格式分区 hinet 免费吧 酷番云 免费的asp空间 国外的代理服务器 独立主机 贵阳电信 lamp是什么意思 摩尔庄园注册 谷歌搜索打不开 新疆服务器 更多