abstract 英文含义是抽象的意思,在 java 中用来修饰类代表的意思是该类为抽象类,不能被实例化,而 Spring 中 bean 标签里的 abstract 的含义也是差不多,该属性的默认值是 false ,表示当前 bean 是一个抽象的 bean 不能被实例化,那么这就有问题了,既然一个 bean 不能被实例化,那么这个 bean 存在的意义是什么?
Spring 之所以这么设计,必然有其存在的道理,在说 abstract 属性之前,我们再来说 bean 标签中的另外一个属性 parent ,顾名思义,就是一个认爸爸的属性,用来表明当前的 bean 的老爸是谁,这样就能顺利的继承它的遗产。。。emmm,说错了,是继承它的属性.
1、创建两个实体类
这里需要说明的一点是,ParentBean 和 ChildrenBean 是可以不需要继承关系的,但是 ChildrenBean 里面的属性一定是要覆盖完全 ParentBean 里面的属性,ChildrenBean 也可以扩展一些自己的属性(height).
public class ParentBean {
private String name;
private Integer age;
private String gender;
// 省略 set/get/toString方法
}
public class ChildrenBean {
private String name;
private String age;
private String gender;
private Double height;
// 省略 set/get/toString方法
}
2、xml配置
<bean id="abstractBean" class="com.xiaomaomao.entity.ParentBean" abstract="true">
<property name="name" value="damaomao"></property>
<property name="age" value="40"></property>
<property name="gender" value="male"></property>
</bean>
// ChildrenBean 会覆盖掉 ParentBean 的属性 name、age 属性,继承gender的属性,同时也扩展了自己的特有属性 height
<bean id="childrenBean" class="com.xiaomaomao.entity.ChildrenBean" parent="abstractBean">
<property name="name" value="xiaomaomao"></property>
<property name="age" value="20"></property>
<property name="height" value="177"></property>
</bean>
3、测试类
public class SpringTest {
public static void main(String[] args) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-config/spring-ioc01.xml");
ChildrenBean childrenBean = (ChildrenBean)ioc.getBean("childrenBean");
System.out.println(childrenBean);
}
}
4、测试结果
通过测试结果我们可以验证我们上面的说法, ChildrenBean 里面覆盖掉了 ParentBean 里面的 name、age 的值,继承了 ParentBean 里面的 gender 属性值,同时自己可以扩展属性 height
ChildrenBean{name='xiaomaomao', age='20', gender='male', height=177.0}
5、扩展
ParentBean 和 ChildrenBean 两个类并不一定要有实际的继承关系,可以是两个普通的类.甚至, parent 属性所指向的 bean 可以不用设置某个具体的类,而只设置它是属性,例如:
<bean id="abstractBean" abstract="true">
<property name="name" value="damaomao"></property>
<property name="age" value="40"></property>
<property name="gender" value="male"></property>
</bean>
<bean id="childrenBean" class="com.xiaomaomao.entity.ChildrenBean" parent="abstractBean">
<property name="name" value="xiaomaomao"></property>
<property name="age" value="20"></property>
<property name="height" value="177"></property>
</bean>
6、总结
在Spring中, abstract 属性一般是用来声明抽象 bean ,将一些公共的属性放到一块,这样就能减少重复的代码.所以在标签中,可以这样设置:
<bean id="abstractBean" abstract="true">
<property name="name" value="damaomao"></property>
<property name="age" value="40"></property>
<property name="gender" value="male"></property>
</bean>
<bean id="childrenBeanA" class="com.xiaomaomao.entity.ChildrenBean" parent="abstractBean">
<property name="name" value="xiaomaomao"></property>
<property name="age" value="20"></property>
<property name="height" value="177"></property>
</bean>
<bean id="childrenBeanB" class="com.xiaomaomao.entity.ChildrenBean" parent="abstractBean">
<property name="name" value="xiaomao"></property>
<property name="age" value="10"></property>
<property name="height" value="160"></property>
</bean>
这样,abstractBean 就起到了一个模板的作用,可以减少重复定义,这里只有简单的几个属性,所以可能看起来不是很直观,可以想象一下,如果 abstractBean 中有一二十个公用属性,是不是可以少写不少代码呢?
abstract 和 parent 属性可以当做用来减少xml重复代码的方法,可以将一些 bean 的公共属性抽取出来,放到一个公共的 bean 中,然后使用上面的栗子进行配置,来让 xml 文件更加简洁.
值得注意的是, parent 属性配置的 bean 之间,并不一定需要有实际的继承关系,更多的是属性的继承.被设置为 parent 的 bean 甚至可以不用映射到某一个具体的类,而仅仅将其当做属性模板来使用.