Spring-Context之九:在bean定义中使用继承
本文内容纲要:Spring-Context之九:在bean定义中使用继承
定义bean时有个abstract属性,可以设置为true或false,默认为false。
12 3 4 | <beanid="animal"class="Animal"abstract="true"><propertyname="name"value="elephant"/><propertyname="legs"value="4”/></bean>
|
这里定义了一个叫elepahnt的animal bean,有4条腿,它与其他bean不同之处是abstract属性为true。这意味着什么?意味着这个bean不能被实例化,不能通过ApplicationContext.getBean()的方式来获取到该bean,也不能使用ref属性引用这个bean。否则会抛出BeanIsAbstractException的异常。
你可能会问?坑爹那?声明一个bean不能被实例化,那有何用?
当然有用,Spring框架开发者也不是一帮吃饱了没事干的人,设计一些没用的功能出来。
这要配合着parent属性来用。
12 3 4 5 6 7 8 9 10 11 12 13 14 | <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="animal"class="Animal"abstract="true"><propertyname="legs"value="4"/></bean><beanid="monkey"parent="animal"><propertyname="name"value="dudu"/></bean></beans>
|
这里有两个bean,一个是animal,指定legs是4,另一个是monkey,通过parent的属性指向animal,指定name为dudu。聪明的读者可能已经猜出来了,parent属性就是子bean可以继承父bean中的属性,并且在子bean中可以重载对应的属性。虽然我们没显式的指定monkey的legs为4,其实它已经从父bean animal中继承了这个属性。这样的好处是如果在定义大量bean时,发先大量bean存在重复属性定义时,可以抽取一个抽象bean出来,实现这些重复的属性定义,让其他bean都使用parent属性指向这个抽象bean。这样可以大大简化bean的配置。
除了使用parent直接引用父bean的class外,另外也可以使用自定义的class。
Monkey.java
12 3 4 5 6 7 8 9 10 11 12 | publicclassMonkeyextendsAnimal{privatebooleancanDrawing;publicbooleanisCanDrawing(){returncanDrawing;}publicvoidsetCanDrawing(booleancanDrawing){this.canDrawing=canDrawing;}}
|
12 3 4 5 6 7 8 9 10 11 12 13 14 15 | <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="animal"class="Animal"abstract="true"><propertyname="legs"value="4"/></bean><beanid="smartMonkey"class="Monkey"parent="animal"><propertyname="name"value="smallDudu"/><propertyname="canDrawing"value="true"/></bean></beans>
|
这样smartMonkey自动继承了父bean中的legs属性,同时它的class类型也是一个新类型。
有人可能要问了,子bean的class与父bean中的class一定要是继承关系吗?答案是否定的。 请看这个修改后的Monkey class,其本身并未从Animal继承。
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | publicclassMonkey{privatebooleancanDrawing;privateStringname;privateintlegs;publicbooleanisCanDrawing(){returncanDrawing;}publicvoidsetCanDrawing(booleancanDrawing){this.canDrawing=canDrawing;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetLegs(){returnlegs;}publicvoidsetLegs(intlegs){this.legs=legs;}}
|
然后还配置同样的bean。
12 3 4 5 6 7 8 9 10 11 12 13 14 15 | <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="animal"class="Animal"abstract="true"><propertyname="legs"value="4"/></bean><beanid="smartMonkey"class="Monkey"parent="animal"><propertyname="name"value="smallDudu"/><propertyname="canDrawing"value="true"/></bean></beans>
|
依然能够正常工作,并且smartMonkey中的legs还是4。
这说明了Spring中使用parent继承父bean中的属性并不需要子bean和父bean的class在一个继承树上。父bean更像一个模板,子bean能够自动使用父bean中的配置而已。唯一需要注意的是在父bean中定义的属性在子bean中都要存在。
那可能有人就有个大胆的猜想了,可不可以定义一个没有class类型的父bean那?这个bean反正不能实例化,只用来让子bean继承属性。答案是肯定的。
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="animal"abstract="true"><propertyname="legs"value="4"/></bean><beanid="monkey"parent="animal"class="Animal"><propertyname="name"value="dudu"/></bean><beanid="smartMonkey"class="Monkey"parent="animal"><propertyname="name"value="smallDudu"/><propertyname="canDrawing"value="true"/></bean></beans>
|
上面的定义依然可以工作。
多说一点,parent也支持对集合属性的继承。比如在父bean中定义了一个属性为List或Map,子bean中也能继承到该List或Map,更强大的是子bean还可以对List或Map进行合并。
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="sampleAccounts"abstract="true"><propertyname="accounts"><map><entrykey="Bob"value="001"/><entrykey="John"value="002"/></map></property></bean><beanid="accountService"parent="sampleAccounts"class="AccountService"><propertyname="accounts"><mapmerge="true"><entrykey="Michael"value="003"/><entrykey="Joel"value="004"/></map></property></bean></beans>
|
在子bean中使用的map元素上使用merge=“true”就可以和父bean中的map条目进行合并。如果指定为false则不会合并,只会使用子bean中定义的map条目。
本例中的源码请在我的GitHub上自行下载。
本文内容总结:Spring-Context之九:在bean定义中使用继承
原文链接:https://www.cnblogs.com/huang0925/p/3644096.html
以上是 Spring-Context之九:在bean定义中使用继承 的全部内容,
来源链接:
utcz.com/z/362553.html