👨👧👦 Spring 框架中的 Bean 继承:parent属性 (XML配置)
在复杂的企业应用中,配置大量相似的组件(如数据访问对象DAODAODAO、服务ServiceServiceService)是常见的需求。这些组件往往需要共享相同的底层资源,例如数据库连接工厂或事务管理器。如果对每个组件都重复编写相同的配置,不仅工作量大,而且难以维护。
Spring 框架通过Bean 定义继承机制解决了这个问题,核心工具就是 Bean 定义中的parent属性。
1.parent属性的核心原理
Spring Bean 的继承,是一种配置数据的继承,而非 Java 类层次结构的继承。它允许一个 Bean 定义(称为子 Bean)从另一个 Bean 定义(称为父 Bean)继承所有的配置信息。
- 父 Bean (Parent Bean):提供一个配置模板。它通常被标记为抽象(
abstract="true"),这意味着 Spring 容器不会尝试创建它的实例,它的唯一作用是作为配置蓝图。 - 子 Bean (Child Bean):通过设置
parent="父 Bean ID"来继承配置。子 Bean 必须指定一个具体的 Java 类,Spring 容器会实例化它。
2. 为什么需要 Bean 继承?
最典型的应用场景是集中管理底层资源依赖。
例如,在一个使用Hibernate或JPA的系统中,所有的DAODAODAO组件都需要注入同一个sessionFactory(会话工厂)。
🚫 不使用继承的问题:配置冗余
XML
<bean id="orderDao" class="com.example.OrderDaoImpl"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="userDao" class="com.example.UserDaoImpl"> <property name="sessionFactory" ref="sessionFactory" /> </bean>✅ 使用继承的解决方案:创建模板
使用parent属性后,配置变得简洁而强大:
步骤一:定义抽象父 Bean 作为模板
首先,定义一个抽象的baseDaoTemplate,集中管理共享的依赖(如sessionFactory)。
XML
<bean id="baseDaoTemplate" abstract="true"> <property name="sessionFactory" ref="sessionFactory" /> </bean>步骤二:子 Bean 继承模板
具体的DAODAODAO组件通过parent属性继承这个模板。
XML
<bean id="orderDao" class="com.example.OrderDaoImpl" parent="baseDaoTemplate"> <property name="modelName" value="Order" /> </bean> <bean id="userDao" class="com.example.UserDaoImpl" parent="baseDaoTemplate"> <property name="modelName" value="User" /> </bean>3. Bean 继承的操作细节
使用parent属性时,子 Bean 拥有极高的灵活性:
| 操作 | 描述 | 示例 |
|---|---|---|
| 继承 | 子 Bean 自动继承父 Bean 的所有配置(例如类名、属性值、构造函数参数等)。 | orderDao自动获得了sessionFactory属性的注入。 |
| 覆盖 | 子 Bean 可以定义与父 Bean 同名的属性,以覆盖父 Bean 的值。 | 如果orderDao想使用另一个sessionFactoryNew,它可以重新定义<property name="sessionFactory" ref="sessionFactoryNew" />来覆盖父 Bean 的配置。 |
| 添加 | 子 Bean 可以定义父 Bean 中没有的新属性,如上例中的modelName。 | orderDao和userDao分别添加了各自的模型名称属性。 |
重要提示:
- 子 Bean 总是使用自己的 Java 类定义。父 Bean 的
class属性会被继承,但子 Bean 如果定义了自己的class,则会覆盖父 Bean 的类。 - 如果父 Bean 是抽象的(
abstract="true"),则它不能被实例化,只能被继承。