Spring系列第13篇:使用继承简化bean配置(abstract & parent)(1)

public ServiceA getServiceA() {

return serviceA;

}

public void setServiceA(ServiceA serviceA) {

this.serviceA = serviceA;

}

@Override

public String toString() {

return “ServiceC{” +

“name='” + name + ‘’’ +

“, serviceA=” + serviceA +

‘}’;

}

}

下面我们使用spring来创建上面3个类对应的bean。

beanExtend.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">

创建测试用例。

BeanExtendTest.java

package com.javacode2018.lesson001.demo12;

import org.junit.Test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**

* 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活!

* bean定义继承案例

*/

public class BeanExtendTest {

@Test

public void normalBean() {

String beanXml = “classpath:/com/javacode2018/lesson001/demo12/normalBean.xml”;

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(beanXml);

System.out.println(“serviceB:” + context.getBean(ServiceB.class));

System.out.println(“serviceC:” + context.getBean(ServiceC.class));

}

}

运行输出

serviceB:ServiceB{name=‘路人甲Java’, serviceA=com.javacode2018.lesson001.demo12.ServiceA@222114ba}

serviceC:ServiceC{name=‘路人甲Java’, serviceA=com.javacode2018.lesson001.demo12.ServiceA@222114ba}

通过继承优化代码

我们再回头去看一下上面xml中,serviceB和serviceC两个bean的定义如下:

这2个bean需要注入的属性的值是一样的,都需要注入name和serviceA两个属性,并且2个属性的值也是一样的,我们可以将上面的公共的代码抽取出来,通过spring中继承的方式来做到代码重用。

可以将上面xml调整一下,我们来新建一个extendBean.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">

上面多了一个baseService的bean,这个bean没有指定class对象,但是多了一个abstract="true"的属性,表示这个bean是抽象的,abstract为true的bean在spring容器中不会被创建,只是会将其当做bean定义的模板,而serviceB和serviceC的定义中多了一个属性parent,用来指定当前bean的父bean名称,此处是baseService,此时serviceB和serviceC会继承baseService中定义的配置信息。

来个测试用例看一下效果:

@Test

public void extendBean() {

String beanXml = “classpath:/com/javacode2018/lesson001/demo12/extendBean.xml”;

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(beanXml);

System.out.println(“serviceB:” + context.getBean(ServiceB.class));

System.out.println(“serviceC:” + context.getBean(ServiceC.class));

}

运行输出:

serviceB:ServiceB{name=‘路人甲Java’, serviceA=com.javacode2018.lesson001.demo12.ServiceA@222114ba}

serviceC:ServiceC{name=‘路人甲Java’, serviceA=com.javacode2018.lesson001.demo12.ServiceA@222114ba}

输出和上面案例的输出基本一致。

但是这次bean xml中bean的定义简化了很多,将公共的bean配置提取出来了,通过parent属性来配置需要继承的bean。

子bean中也可以重新定义父bean中已经定义好的配置,这样子配置会覆盖父bean中的配置信息,我们将extendBean.xmlserviceC的定义改一下:

运行extendBean输出:

serviceB:ServiceB{name=‘路人甲Java’, serviceA=com.javacode2018.lesson001.demo12.ServiceA@222114ba}

serviceC:ServiceC{name=‘欢迎和【路人甲Java】一起学些spring!’, serviceA=com.javacode2018.lesson001.demo12.ServiceA@222114ba}

从输出中可以看出serviceC中的name对父bean中name的值进行了覆盖。

我们再来从容器中获取一下baseService,如下:

System.out.println(context.getBean(“baseService”));

运行输出:

org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name ‘baseService’: Bean definition is abstract

at org.springframework.beans.factory.support.AbstractBeanFactory.checkMergedBeanDefinition(AbstractBeanFactory.java:1412)

会报BeanIsAbstractException异常,因为baseService是抽象的,不能够创建这个bean实例。

总结

  1. bean元素的abstract属性为true的时候可以定义某个bean为一个抽象的bean,相当于定义了一个bean模板,spring容器并不会创建这个bean,从容器中查找abstract为true的bean的时候,会报错BeanIsAbstractException异常

  2. bean元素的parent属性可以指定当前bean的父bean,子bean可以继承父bean中配置信息,也可以自定义配置信息,这样可以覆盖父bean中的配置

案例源码

链接:https://pan.baidu.com/s/1p6rcfKOeWQIVkuhVybzZmQ

提取码:zr99

Spring系列

  1. Spring系列第1篇:为何要学spring?

  2. Spring系列第2篇:控制反转(IoC)与依赖注入(DI)

  3. Spring系列第3篇:Spring容器基本使用及原理

  4. Spring系列第4篇:xml中bean定义详解(-)

  5. Spring系列第5篇:创建bean实例这些方式你们都知道?

  6. Spring系列第6篇:玩转bean scope,避免跳坑里!

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

Java架构进阶面试及知识点文档笔记

这份文档共498页,其中包括Java集合,并发编程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面试解析及知识点整理

image

Java分布式高级面试问题解析文档

其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!

image

互联网Java程序员面试必备问题解析及文档学习笔记

image

Java架构进阶视频解析合集
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
8页,其中包括Java集合,并发编程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面试解析及知识点整理**

[外链图片转存中…(img-88Xg67yE-1713427904232)]

Java分布式高级面试问题解析文档

其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!

[外链图片转存中…(img-o9LiUYO6-1713427904232)]

互联网Java程序员面试必备问题解析及文档学习笔记

[外链图片转存中…(img-w5iXVeyX-1713427904232)]

Java架构进阶视频解析合集
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值