创建一个ServiceA.java文件
package com.example.demo.demo;
public class ServiceA {
}
分别创建ServiceB.java和ServiceC.java依赖ServiceA
package com.example.demo.demo;
public class ServiceB {
private String name;
private ServiceA serviceA;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ServiceA getServiceA() {
return serviceA;
}
public void setServiceA(ServiceA serviceA) {
this.serviceA = serviceA;
}
@Override
public String toString() {
return "ServiceB{" +
"name='" + name + '\'' +
", serviceA=" + serviceA +
'}';
}
}
通过配置文件配置,实现依赖
<bean id="serviceA2" class="com.example.demo.demo.ServiceA"></bean>
<bean id="serviceB2" class="com.example.demo.demo.ServiceB">
<property name="serviceA" ref="serviceA2"></property>
<property name="name" value="我是serviceB"></property>
</bean>
<bean id="serviceC2" class="com.example.demo.demo.ServiceC">
<property name="serviceA" ref="serviceA2"></property>
<property name="name" value="我是serviceC"></property>
</bean>
测试类。分别从容器中获取到serviceB2与serviceC2
System.out.println("spring容器启动中...");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
System.out.println(context.getBean("serviceA2"));
System.out.println(context.getBean("serviceB2"));
System.out.println(context.getBean("serviceC2"));
System.out.println("spring容器启动完毕!");
控制台如下
spring容器启动中...
com.example.demo.demo.ServiceA@6d5037a9
ServiceB{name='我是serviceB', serviceA=com.example.demo.demo.ServiceA@6d5037a9}
ServiceC{name='我是serviceC', serviceA=com.example.demo.demo.ServiceA@6d5037a9}
spring容器启动完毕!
这2个bean需要注入的属性的值是一样的,都需要注入name和serviceA两个属性,并且2个属性的值也是一样的,我们可以将上面的公共的代码抽取出来,通过spring中继承的方式来做到代码重用
<!-- 使用继承简化bean的配置-->
<bean id="serviceA2" class="com.example.demo.demo.ServiceA"></bean>
<!--抽取公共部分-->
<bean id="serviceAImp" abstract="true">
<property name="serviceA" ref="serviceA2"></property>
<property name="name" value="我是抽取公共部分"></property>
</bean>
<bean id="serviceB2" class="com.example.demo.demo.ServiceB" parent="serviceAImp">
</bean>
<bean id="serviceC2" class="com.example.demo.demo.ServiceC" parent="serviceAImp">
<property name="name" value="我是serviceC"></property>
</bean>
上面多了一个serviceAImp的bean,这个bean没有指定class对象,但是多了一个abstract="true"的属性,表示这个bean是抽象的,abstract为true的bean在spring容器中不会被创建,只是会将其当做bean定义的模板,而serviceB和serviceC的定义中多了一个属性parent,用来指定当前bean的父bean名称,此处是serviceAImp,此时serviceB和serviceC会继承serviceAImp中定义的配置信息
总结
1、 bean元素的abstract属性为true的时候可以定义某个bean为一个抽象的bean,相当于定义了一个bean模板,spring容器并不会创建这个bean,从容器中查找abstract为true的bean的时候,会报错BeanIsAbstractException异常
2、bean元素的parent属性可以指定当前bean的父bean,子bean可以继承父bean中配置信息,也可以自定义配置信息,这样可以覆盖父bean中的配置