当前位置: 首页 > news >正文

Spring Bean定义继承:配置复用的高效技巧

🌱 一、什么是 Bean Definition?

在 Spring 中,Bean Definition 是对一个 Bean 的“蓝图”或“配置描述”,它包含了创建 Bean 所需的所有信息,比如:

  • 类名(class
  • 构造函数参数(constructor-arg
  • 属性值(property
  • 初始化方法(init-method
  • 销毁方法(destroy-method
  • 是否单例(singleton)、是否懒加载(lazy-init)等

💡 注意:Bean Definition ≠ 实例。它是“怎么创建 Bean”的说明书,而不是 Bean 本身。


🔗 二、Bean Definition 的继承是什么?

就像 Java 类可以继承父类一样,Spring 允许一个 Bean Definition 继承另一个 Bean Definition。这个“继承”不是 Java 类的继承,而是 配置层面的继承

✅ 子 Bean 可以:
  • 继承父 Bean 的配置(如属性值、构造参数、初始化方法等)
  • 覆盖父 Bean 的某些配置
  • 添加新的配置

🎯 目的:避免重复写大量相似的 Bean 配置,实现“模板化”。


🧩 三、如何配置 Bean 继承?(XML 示例)

<!-- 父 Bean 定义 -->
<bean id="inheritedTestBean" abstract="true"class="org.springframework.beans.TestBean"><property name="name" value="parent"/><property name="age" value="1"/>
</bean><!-- 子 Bean 定义 -->
<bean id="inheritsWithDifferentClass"class="org.springframework.beans.DerivedTestBean"parent="inheritedTestBean"init-method="initialize"><property name="name" value="override"/><!-- age 会从父类继承,值为 1 -->
</bean>
解读:
  1. parent="inheritedTestBean":表示这个 Bean 继承自 inheritedTestBean
  2. abstract="true":表示这个父 Bean 是“抽象的”,不能被实例化。
  3. 子 Bean 没有设置 age,所以会继承父 Bean 的 age=1
  4. 子 Bean 设置了 name="override",所以会覆盖父 Bean 的 name="parent"
  5. 子 Bean 新增了 init-method="initialize",这是父 Bean 没有的。

📚 四、抽象 Bean(Abstract Bean)

什么是抽象 Bean?
  • abstract="true" 标记的 Bean。
  • 它不能被实例化(不能通过 getBean() 获取)。
  • 它的作用是作为一个“模板”,专门供其他 Bean 继承。
为什么需要抽象 Bean?

想象你有多个类似的 Bean,它们共享一些配置,但各自又有差异。如果不使用继承,你会写很多重复代码:

<bean id="bean1" class="com.example.User"><property name="company" value="ABC公司"/><property name="department" value="研发部"/><property name="name" value="张三"/>
</bean><bean id="bean2" class="com.example.User"><property name="company" value="ABC公司"/><property name="department" value="研发部"/><property name="name" value="李四"/>
</bean>

使用抽象 Bean 改造:

<bean id="userTemplate" abstract="true" class="com.example.User"><property name="company" value="ABC公司"/><property name="department" value="研发部"/>
</bean><bean id="bean1" parent="userTemplate"><property name="name" value="张三"/>
</bean><bean id="bean2" parent="userTemplate"><property name="name" value="李四"/>
</bean>

✅ 大大减少了重复配置!


⚠️ 五、继承规则总结

配置项是否继承?说明
class❌ 不强制继承,可覆盖如果子 Bean 不写 class,则使用父的;写了就用自己的(但必须兼容父类属性)
scope✅ 继承如 singleton、prototype
constructor-arg✅ 继承构造函数参数也会继承
property✅ 继承属性值会继承,子类可覆盖
init-method / destroy-method✅ 可覆盖子类设置会覆盖父类
depends-on, autowire, lazy-init❌ 不继承这些总是取子类的定义

🚫 六、抽象 Bean 的注意事项

  1. 不能实例化抽象 Bean
    如果你尝试:

    context.getBean("userTemplate"); // 抛异常!
    

    会报错,因为抽象 Bean 是“不完整的”,只是模板。

  2. ApplicationContext 默认预实例化单例 Bean
    Spring 容器启动时,会自动创建所有 singleton Bean。
    所以如果你有一个 Bean 是用来做模板的(即使它有 class),必须加上 abstract="true",否则 Spring 会试图创建它,可能出错。


🧠 七、什么时候用 Bean 继承?

适用于以下场景:

  • 多个 Bean 配置高度相似,只有少量差异。
  • 想统一管理公共配置(如数据库连接池、日志配置等)。
  • 使用 XML 配置时,减少冗余代码。
  • 需要动态生成 Bean 配置(结合 ChildBeanDefinition 编程式使用)。

🔄 八、Java Config 中的等价写法(补充)

虽然原文讲的是 XML,但在现代 Spring(基于注解和 Java Config)中,Bean 继承的概念不太直接支持,但可以通过以下方式模拟:

@Configuration
public class BeanConfig {@Bean("parentBean")public TestBean parentBean() {TestBean bean = new TestBean();bean.setName("parent");bean.setAge(1);return bean;}@Bean("childBean")public DerivedTestBean childBean() {DerivedTestBean bean = new DerivedTestBean();// 手动“继承”父 Bean 的属性bean.setName("override");bean.setAge(parentBean().getAge()); // 继承 ageinitialize(); // 调用 init-methodreturn bean;}public void initialize() {// init logic}
}

⚠️ 注意:Java Config 中没有原生的“继承”机制,需要手动处理。


✅ 总结:一句话理解

Bean Definition 继承是一种配置复用机制,允许一个 Bean 定义(子)继承另一个 Bean 定义(父)的配置,支持覆盖和扩展,常用于通过抽象模板减少重复配置。


🎯 类比理解(通俗版)

想象你在填简历:

  • 父 Bean = 一份“通用简历模板”,写着“公司:阿里巴巴,部门:技术部”
  • 子 Bean = 每个员工的简历,继承模板,但可以修改“姓名”、“工号”等

这样你就不用每份简历都写一遍“公司:阿里巴巴”,只需改个别信息即可。


如果你还有具体的疑问(比如某个例子不理解,或想看编程式用法),欢迎继续提问!

http://www.dtcms.com/a/529185.html

相关文章:

  • 湖北网站建设专家本地搭建linux服务器做网站
  • 龙华建网站百度账号官网
  • Python高效爬虫:使用twisted构建异步网络爬虫详解
  • 做爰片的网站公司企业网络宣传设计方案
  • 基于鸿蒙UniProton的PLC控制系统开发指南
  • 建设部网站查询造价师证件地方门户网站的前途
  • 【案例实战】HarmonyOS SDK新体验:利用近场能力打造无缝的跨设备文件传输功能
  • AI边缘设备时钟设计突围:从ppm级稳定到EMC优化的全链路实践
  • typescript—元组类型介绍
  • 限元方法进行电磁-热耦合模拟
  • 三维网站搭建教程直播网站app开发
  • 品牌网站建设 优帮云在百度上做个网站多少合适
  • 无聊。切个水题。
  • 公司微信网站制作wordpress插件汉化教程视频
  • 海东营销网站建设公司福州seo关键词
  • 松江 企业网站建设怎么样做移动油光文字网站
  • 无法生成dump——MiniDumpWriteDump 阻塞原因分析
  • 如何在1v1一对一视频直播交友APP中实现防录屏防截屏功能?
  • 网站做新闻外链有作用吗营销导向的网站建设的主要流程
  • C++笔记(面向对象)对于对象返回方式的讲解
  • CMP(类ClouderaCDP7.3(404次编译) )完全支持华为鲲鹏Aarch64(ARM)POC报告
  • 网站后台管理系统破解网站建设目标规划
  • 在本地生活赛道,如何打造属于自己的业务护城河?
  • 云南省建设厅网站查询企业oa办公软件
  • 网站如何做搜狗搜索引擎合肥网红打卡地
  • PPIO上线DeepSeek-OCR模型
  • AtCoder Beginner Contest 426 题解
  • 服务器 网站 app网络技术员工作内容
  • 基于用户反馈的 Elastic Kibana 9.2 导航刷新
  • 哪里有建设网站网站空间大小怎么看