bean定义也可以像类的定义一样,可以有一个父类模板,供子类继承。
举一个例子:
public class TestBean {
private String str1;
private String str2;
public void setStr1(String str1) {
this.str1 = str1;
}
public void setStr2(String str2) {
this.str2 = str2;
}
@Override
public String toString() {
return "TestBean [str1=" + str1 + ", str2=" + str2 + "]";
}
}
配置元数据:
<bean id="parent" class="SpringTest.beanInheritance.TestBean">
<property name="str1" value="parent's setting on str1"/>
<property name="str2" value="parent's setting on str2"/>
</bean>
<bean id="child" parent="parent" class="SpringTest.beanInheritance.TestBean" scope="prototype">
<property name="str1" value="child's setting on str1"/>
</bean>
客户端:
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(Main.class.getResource("") + "beans.xml");
System.out.println("----parent's info----");
System.out.println(context.getBean("parent"));
System.out.println("Is it singleton ? " + context.isSingleton("parent"));
System.out.println();
System.out.println("---- child's info----");
System.out.println(context.getBean("child"));
System.out.println("Is it singleton ? " + context.isSingleton("child"));
}
}
运行结果:
解释:通过parent属性指定要继承的bean定义,如果自定义和父定义冲突,则以子定义为准(例如上面的scope属性,父定义是singleton,子定义是prototype,子定义继承之后,以子定义为准);如果子定义不覆盖父定义,则继承
与类的继承很相似,如果不覆盖就继承。
abstract属性
bean定义继承的用处其实就是提供“模板”。既然是模板,父定义就不应该被初始化,因此,引入abstract属性。
<bean id="beanName" abstract="true"/>
When a definition is abstract, it is usable only as a pure template bean definition that serves as a parent definition for child definitions. Trying to use such an abstract parent bean on its own, by referring to it as a ref property of another bean or doing an explicit getBean() call with the parent bean ID returns an error.
如果一个bean定义被声明为abstract,这个bean就会变成一个纯的模板,供子定义继承。如果试图使用依赖注入或者getBean()的方式请求这个abstract="true"的bean,就会出错
默认情况下容器会预实例化所有的单例bean。因此,对于仅仅是作为模板(不需要实例化)的父定义,应该确保它的abstract="true",否则,这个模板就会被实例化(模板本身不会被使用,所以没必要实例化)
abstract="true"的bean,不需要指定class属性
仅仅作为模板的定义,是不需要指定class属性,即使指定了,也不会实例化,所以class属性是没有用处的,加上这个属性反而降低了可读性。