Spring-Context之九:在bean定义中使用继承

本文内容纲要:Spring-Context之九:在bean定义中使用继承

定义bean时有个abstract属性,可以设置为true或false,默认为false。

1

2

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属性来用。

1

2

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

1

2

3

4

5

6

7

8

9

10

11

12

publicclassMonkeyextendsAnimal{

privatebooleancanDrawing;

publicbooleanisCanDrawing(){

returncanDrawing;

}

publicvoidsetCanDrawing(booleancanDrawing){

this.canDrawing=canDrawing;

}

}

1

2

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继承。

1

2

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。

1

2

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继承属性。答案是肯定的。

1

2

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进行合并。

1

2

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

回到顶部