随着应用程序规模的增大,Spring配置文件的增长速度更快。当应用中组件越来越多时,Spring配置文件里的Bean配置也随之大幅度增加,慢慢地就会出现一种现象:有一批Bean配置的大量配置信息完全相同,只有少量配置不同。那么我们是否有办法来简化这种配置呢?
Spring提供了 Bean继承 来应对这个问题。Spring可以先为这批Bean配置一个Bean模板,将这批Bean中相同的配置信息配置成Bean模板,因为Spring容器无须创建Bean模板的实例,所以通常将这个Bean模板配成抽象Bean。
将大部分相同信息配置成Bean模板后,将实际的Bean实例配置成Bean模板的子Bean即可。子Bean定义可以从父Bean继承实现类、构造器参数、属性值等配置信息,除此之外,子Bean配置可以增加新的配置信息,并可指定新的配置信息覆盖父Bean的定义。
子Bean无法从父Bean继承如下属性:depends-on、autowire、singleton、scope、lazy-init,这些属性将总是从子Bean定义中获得,或采取默认值。
通过为一个<bean.../>元素指定 parent属性 即可指定该Bean是一个子Bean,parent属性指定该Bean所继承的父Bean的id。
Axe.java :
public interface Axe {
public String chop();
}
SteelAxe.java :
public class SteelAxe implements Axe {
@Override
public String chop() {
return "钢斧砍柴真快";
}
public SteelAxe() {
System.out.println("Spring实例化依赖bean:SteelAxe实例...");
}
}
StoneAxe.java :
public class StoneAxe implements Axe {
@Override
public String chop() {
return "石斧砍柴真慢";
}
public StoneAxe() {
System.out.println("Spring实例化依赖bean:StoneAxe实例...");
}
}
Person.java :
public interface Person {
public void useAxe();
}
Chinese.java :
public class Chinese implements Person{
private Axe axe;
public void setAxe(Axe axe) {
System.out.println("Spring执行依赖关系注入...");
this.axe = axe;
}
public Chinese() {
System.out.println("Spring实例化主调bean:Chinese实例...");
}
@Override
public void useAxe() {
System.out.println(axe.chop());
}
}
bean.xml核心配置:
<bean id="steelAxe" class="com.bean.SteelAxe"/>
<bean id="stoneAxe" class="com.bean.StoneAxe"/>
<bean id="chineseTemplate" class="com.bean.Chinese" abstract="true">
<property name="axe" ref="steelAxe"/>
</bean>
<bean id="chinese" parent="chineseTemplate"/>
Test.java :
public class Test {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
Person p=(Person) ctx.getBean("chinese");
p.useAxe();
}
}
运行Test.java,控制台输出:
子Bean从父Bean继承了实现类,依赖关系等配置信息。实际上,子Bean也可以覆盖父Bean的配置信息:
<bean id="steelAxe" class="com.bean.SteelAxe"/>
<bean id="stoneAxe" class="com.bean.StoneAxe"/>
<bean id="chineseTemplate" class="com.bean.Chinese" abstract="true">
<property name="axe" ref="steelAxe"/>
</bean>
<bean id="chinese" parent="chineseTemplate">
<property name="axe" ref="stoneAxe"/>
</bean>
再次运行Test.java,控制台输出: