Bean的定义可以包括很多的配置信息,包括构造参数,属性
等等,也可以包括一些容器指定的信息,比如初始化方法,工厂方法
等等。子Bean会继承父Bean的配置信息。子Bean也可以覆盖父Bean的一些值,或者增加一些值。通过定义父Bean和子Bean可以减少配置内容,是一种高效的模板性能
。
如果开发者通过编程的方式跟ApplicationContext交流,就会知道子Bean是通过ChildBeanDefinition类
表示的
具体的演示如下:
/**
* @Project: spring
* @description: 抽象父类
* @author: sunkang
* @create: 2018-09-17 15:55
* @ModificationHistory who when What
**/
public class AbstractParent {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
/**
* @Project: spring
* @description: 具体的子类
* @author: sunkang
* @create: 2018-09-17 15:57
* @ModificationHistory who when What
**/
public class ConcreteChild extends AbstractParent{
}
在spring-inheritance.xml的配置中如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--如果父类的是抽象,指明absract=true,表示该类不能被实例化, class属性可以指定也可以不指定-->
<bean id="parent" abstract="true" class="com.spring.inheritance.AbstractParent">
<property name="name" value="parent"/>
<property name="age" value="50"/>
</bean>
<bean id="child" class="com.spring.inheritance.ConcreteChild" parent="parent">
<!--会覆盖父类的方法-->
<property name="name" value="child"/>
</bean>
</beans>
测试案例:
/**
* @Project: spring
* @description: 继承的测试
* @author: sunkang
* @create: 2018-09-17 16:00
* @ModificationHistory who when What
**/
public class InheritanceTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("inheritance/spring-inheritance.xml");
ConcreteChild child= context.getBean("child",ConcreteChild.class);
System.out.println("name:"+child.getName());
System.out.println("age:"+child.getAge());
}
}
测试结果如下:
name:child
age:50
总结:父Bean是无法被实例化的,因为它是不完整的,会被标志位abstract。当使用abstract的时候,其配置就作为纯模板来使用了。如果尝试在abctract的父Bean中引用了其他的Bean或者调用getBean()都会返回错误。容器内部的preInstantiateSingletons()方法会忽略掉那些定义为抽象的Bean。