Spring中bean的继承与抽象代码示例
发布时间 - 2026-01-11 03:24:02 点击率:次我们在应用Spring时,在一般的设计时,肯定要用的抽象类。那在Spring中怎么样配置这些抽象Bean呢。请看下面:

如果两个bean 之间的配置信息非常相似,可利用继承来减少重复配置工作。
继承是指子bean 定义可从父bean 定义继承部分配置信息,也可覆盖特定的配置信息,或者添加一些配置。使用继承配置可以节省很多的配置工作。在实际应用中,通用配置会被配置成模板,可供子bean 继承。
使用abstract 属性
正如前面所介绍的,通用的配置会被配置成模板,而模板不需要实例化,仅仅作为子bean 定义的模板使用。而ApplicationContext 默认预初始化所有的singleton bean 。使用abstract 属性,可以阻止模板bean 被预初始化。abstract 属性为true 的bean 称为抽象bean ,容器会忽略所有的抽象bean 定义,预初始化时不初始化抽象bean。如果没有定义abstract 属性,该属性默认为false 。如下配置文件定义了一个抽象bean ,该抽象bean 作为模板使用:
public class SteelAxe implements Axe
{
//count 是个状态值,每次执行chop 方法该值增加1
private int count = 0;
public SteelAxe(){
System.out.println("Spring实例化依赖bean: SteelAxe 实例.. .");
}
//测试用方法
public String chop(){
return "钢斧砍柴真快" + ++count;
}
}
public class Chinese implements Person
//面向Axe 接口编程,而不是具体的实现类
private Axe axe;
//默认的构造器
public Chinese(){
System.out.println("Spring实例化主调bean: Chinese 实例... ");
}
//设值注入所需的setter 方法
public void setAxe( Axe axe){
System.out.pr工ntln (" Spring 执行依赖关系注入...");
this.axe = axe;
}
//实现Person 接口的useAxe 方法
public void useAxe(){
System.out.println(axe.chop());
}
}
<?xml version="1.0" encoding="gb2312"?> <!一指定Spring 配置文件的dtd> <lDOCTYPE beans PUBL工C "-//SPRING//DTD BEAN//EN" ''http://www.springframework.org/dtd/spring-beans.dtd''> <!一Spring 配置文件的根元素一〉 <beans> <bean id="steelAxe" class="lee.SteelAxe"/> <!… 通过abstract 属性定义该bean 是抽象bean--> <bean id="chineseTemplate" class="lee.Chinese" abstract="true"> <!一定义依赖注入的属性一〉 <property name="axe"> <ref local="steelAxe"/> </property> </bean> </beans>
从配置文件中可以看出,抽象bean 的定义与普通bean 的定义几乎没有区别,仅仅增加abstract 属性为true ,但主程序执行结果却有显著的差别。下面的主程序采用AppliactionContext 作为Spring 容器, AppliationContext 默认预初始化所有的singleton bean。其主程序部分如下:
public class BeanTest
{
public static void main(String[] args)throws Exception{
ApplicationContext ctx = new FileSysternXmlApplicationContext("bean.xml");
}
}
//主程序部分仅仅实例化了ApplicationContext,在实例化ApplicationContext时,默认实例化singleton bean。
程序执行结果如下:
Spring 实例化依赖bean: SteelAxe 实例.. .
容器并没有实例化chineseTemplate bean ,而忽略了所有声明为abstract 的beano 如果取消abstract 属性定义,则程序执行结果如下:
Spring 实例化依赖bean: SteelAxe 实~J...
Spring 实例化主调bean: Chinese 实例.. .
Spring 执行依赖关系注入...
可以看出,抽象bean 是一个bean 模板,容器会忽略抽象bean 定义,因而不会实例化抽象bean。但抽象bean 无须实例化,因此可以没有class 属性。如下的配置文件也有效:
<?xml version="1.0" e口coding="gb2312"?> <!一指定Spring 配置文件的dtd> <!DOCTYPE beans PUBLIC "-/!SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd''> <! -- Spring 配置文件的根元素--> <beans> <bean id="steelAxe" class="lee.SteelAxe"/> <!一通过abstract 属性定义该bean 是抽象bean,抽象bean 没有指定class 属性一〉 <bean id="chineseTemplate" abstract="true"> <!… 定义依赖注入的属性一〉 <property name="axe"> <ref local="steelAxe"/> </property> </bean〉 </beans>
注意:抽象bean 不能实例化,既不能通过getBean 获得抽象bean,也不能让其他bean 的ref 属性值指向抽象bean,因而只要企图实例化抽象bean,都将导致错误。
定义子bean
我们把指定了parent 属性值的bean 称为子bean; parent 指向子bean 的模板,称为父bean 。子bean 可以从父bean 继承实现类、构造器参数及属性值,也可以增加新的值。如果指定了init-method , destroy-method 和factory-method 的属性,则它们会覆盖父bean的定义。子bean 无法从父bean 继承如下属性: depends-on, autowire, dependency-check,singleton, lazy-init。这些属性将从子bean 定义中获得,或采用默认值。通过设置parent 属性来定义子bean , parent 属性值为父bean id。修改上面的配置文件如下,增加了子bean 定义:
<?xml version="1.0" encoding="gb2312"?> <!一指定Spring 配置文件的dtd> <lDOCTYPE beans PUBL工C "-//SPRING//DTD BEAN//EN" ''http://www.springframework.org/dtd/spring-beans.dtd''> <!-- Spring 配置文件的根元素一〉 <beans> <bean id="steelAxe" class="lee.SteelAxe"/> <!一通过abstract 属性定义该bean 是抽象bean--> <bean id="chineseTemplate" class="lee.Chinese" abstract="true"> <!-- 定义依赖注入的属性一〉 <property name="axe"> <ref local="steelAxe"/> </property> </bean> <!一通过parent 属性定义子bean ? <bean id="chinese" parent="chineseTemplate"/> </beans>
子bean 与普通bean 的定义并没有太大区别,仅仅增加了parent 属性。子bean 可以没有class 属性,若父bean 定义中有class 属性,则子bean 定义中可省略其class 属性,但子bean 将采用与父bean 相同的实现类。
测试程序修改如下:
public class BeanTest
{
public static void main(String[] args)throws Exception{
ApplicationContext ctx = new FileSysternXmlApplicationContext("bean.xml");
Person p = (Person)ctx.getBean("chinese");
p.useAxe();
}
}
程序执行结果如下:
Spring 实例化依赖bean: Stee1Axe 实例.. .
Spring实例化主调bean: Chinese 实例.. .
spring 执行依赖关系注入...
钢斧砍柴真快
另外,子bean 从父bean 定义继承了实现类并依赖bean 。但子bean 也可覆盖父bean的定义,看如下的配置文件:
//Axe 的实现类StoneAxe如下:
public class StoneAxe implements Axe
//默认构造器
public StoneAxe(){
System.out.println("Spring实例化依赖bean: StoneAxe实例.. .");
}
//实现Axe 接口的chop 方法
public String chop(){
return "石斧砍柴好慢";
}
}
Chinese子类如下:
public class Shanghai extends Chinese {
public void show() {
System.out.println("子Bean ,中国的上海");
}
}
<?xm1 version="1.0" encoding="gb2312"?> <! 指定Spring 配置文件的dtd> <lDOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ''http://www.springframework.org/dtd/spring-beans.dtd''> <! -- Spring 配置文件的根元素一〉 <beans> <bean id="steelAxe" class="lee.SteelAxe"/> <bean id="stoneAxe" class="lee.StoneAxe"/> <!一通过abstract 属性定义该bean 是抽象bean--> <bean id="chineseTemplate" class="lee.Chinese" abstract="true"> <property name="axe"> <ref local="steelAxe"/> </property> </bean> <!一通过parent 属性定义子bean--> <bean id="shanghai" parent="chineseTemplate"> <!一覆盖父bean 的依赖定义…〉 <property name="axe"> <ref local="stoneAxe"/> </property> </bean> </beans>
此时,子bean 的依赖不再是父bean 定义的依赖了。注意,这个时候的父类lee.Chinese 不能是抽象类,(说明下:有abstract="true")不一定说明这个类一定是个抽象类,不是抽象类同样可以在Spring里定义为抽象Bean,如果你的Class是抽象类,那这个时候就不能用父Bean的Class,一定要在子Bean中定义Class来初始化这个子Bean)
测试程序修改如下:
public class BeanTest
{
public static void main(String[] args)throws Exception{
ApplicationContext ctx = new FileSysternXmlApplicationContext("bean.xml");
Person p = (Person)ctx.getBean("shanghai");
p.useAxe();
}
}
按上面的测试程序执行结果如下:
Spring 实例化依赖bean: SteelAxe 实例.. .
spring 实例化依赖bean: StoneAxe 实例.. .
Spring 实例化主调bean: Chinese 实例.. .
Spring 执行依赖关系注入...
石斧砍柴好慢
注意:上例中的子bean 定义都没有class 属性,因为父bean 定义中已有class 属性,子bean 的class 属性可从父bean 定义中继承,但需要注意的是从父Bean继承Class时,父Bean一定不能是抽象类,因为抽象类不能创建实例;如果父bean 定义中也没有指定class 属性,则子bean 定义中必须指定class 属性,否则会出错;如果父bean 定义指定了class 属性,子bean 定义也指定了class 属性,则子bean 将定义的class 属性覆盖父bean 定义的class属性。
Spring 中bean的继承和Java中的继承截然不同,前者是实例与实例之间的参数的延续,后者是一般到特殊的细化,前者是对象和对象之间的关系,后者是类和类之间的关系。
a.Spring中的子bean和父bean可以是不同的类型,但是Java中的继承,子类是一种特殊的父类;
b.Spring中的bean的继承是实例之间的关系,主要表现在参数的延续,而Java中的继承是类与类之间的关系,主要体现在方法和属性的延续。
c.Spring中子bean不可以作为父bean使用,不具备多态性,Java中的子类实例完全可以当作父类实例使用。
总结
本文有关Spring中bean的继承与抽象代码示例的内容就到这里,希望对大家有所帮助。有兴趣的朋友可以参阅本站其他专题,精彩不断。感谢大家对本站的支持!
# spring
# bean
# 继承
# 抽象类
# 详解Spring 中如何控制2个bean中的初始化顺序
# Spring @Bean vs @Service注解区别
# 详解Spring简单容器中的Bean基本加载过程
# Spring Boot如何动态创建Bean示例代码
# 详解Spring中bean的几种注入方式
# Spring boot将配置属性注入到bean类中
# Java中Spring获取bean方法小结
# Spring中如何动态注入Bean实例教程
# Spring多种加载Bean方式解析
# Spring实战之抽象Bean和子Bean定义与用法示例
# 配置文件
# 主程序
# 子类
# 是个
# 为父
# 也可
# 这个时候
# 可以看出
# 真快
# 增加了
# 是一个
# 也不
# 是一种
# 不需要
# 就不
# 已有
# 是指
# 不可以
# 中有
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何生成和使用数据填充?(Seeder和Factory示例)
香港网站服务器数量如何影响SEO优化效果?
详解Oracle修改字段类型方法总结
Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】
如何快速打造个性化非模板自助建站?
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
如何快速配置高效服务器建站软件?
Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势
JavaScript如何实现音频处理_Web Audio API如何工作?
C++用Dijkstra(迪杰斯特拉)算法求最短路径
Laravel如何记录自定义日志?(Log频道配置)
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】
佛山企业网站制作公司有哪些,沟通100网上服务官网?
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
网站制作壁纸教程视频,电脑壁纸网站?
Java遍历集合的三种方式
HTML 中动态设置元素 name 属性的正确语法详解
google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
Linux系统运维自动化项目教程_Ansible批量管理实战
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
英语简历制作免费网站推荐,如何将简历翻译成英文?
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】
免费网站制作appp,免费制作app哪个平台好?
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程
如何在建站之星绑定自定义域名?
北京网站制作公司哪家好一点,北京租房网站有哪些?
b2c电商网站制作流程,b2c水平综合的电商平台?
JS中对数组元素进行增删改移的方法总结
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
南京网站制作费用,南京远驱官方网站?
php做exe能调用系统命令吗_执行cmd指令实现方式【详解】
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
如何基于云服务器快速搭建个人网站?
详解jQuery中基本的动画方法
Laravel用户密码怎么加密_Laravel Hash门面使用教程
如何在阿里云虚拟服务器快速搭建网站?
利用python获取某年中每个月的第一天和最后一天
安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出
如何制作一个表白网站视频,关于勇敢表白的小标题?
Laravel如何与Pusher实现实时通信?(WebSocket示例)
如何在IIS7上新建站点并设置安全权限?
如何在 Pandas 中基于一列条件计算另一列的分组均值
Swift开发中switch语句值绑定模式
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
如何用景安虚拟主机手机版绑定域名建站?
活动邀请函制作网站有哪些,活动邀请函文案?

