7.8 深入理解容器中的Bean 7.8.1 抽象Bean与子Bean
7.8 深入理解容器中的Bean
Spring
框架绝大部分工作都集中在对容器中Bean
的管理上,包括管理容器中Bean
的生命周期、使用Bean
继承等特殊功能。通过深入的管理,应用程序可以更好地使用这些Java
组件(容器中的Bean
对应用而言,往往是一个组件)。
7.8.1 抽象Bean与子Bean
在实际开发中,可能出现的场景是:随着项目越来越大, Spring
配置文件中出现了多个<bean>
配置具有大致相同的配置信息,只有少量信息不同,这将导致配置文件出现很多重复的内容。如果保留这种配置,则可能导致的问题是:
- 配置文件臃肿。
- 后期难以修改、维护。
为了解决上面问题,可以考虑把多个<bean>
配置中相同的信息提取出来,集中成配置模板——这个配置模板并不是真正的Bean
,因此Spring
不应该创建该配置模板,于是需要**为该<bean>
配置增加abstract="true"
属性,这就是抽象Bean
**。
抽象Bean
不能被实例化, Spring
容器不会创建抽象Bean
实例。抽象Bean
的价值在于被继承,抽象Bean
通常作为父Bean
让子Bean
继承。
抽象Bean
只是配置信息的模板,指定abstract="true"
属性即可阻止Spring
实例化该Bean
,因此抽象Bean
可以不指定class
属性。
抽象Bean不能实例化
抽象Bean
不能实例化,因此既不能通过getBean()
显式地获得抽象Bean
实例,也不能将抽象Bean
注入成其他Bean
依赖。不管怎样,只要程序企图实例化抽象Bean
,都将导致错误.
父Bean中可以继承的配置信息
将大部分相同信息配置成抽象Bean
之后,将实际的Bean
实例配置成该抽象Bean
的子Bean
即可。子Bean
定义可以从父Bean
继承实现类
、构造器参数
、属性值
等配置信息,除此之外,子Bean
配置可以增加新的配置信息,并可指定新的配置信息覆盖父Bean
的定义。
子bean元素通过parent属性指定其父bean
通过为一个<bean>
元素指定parent
属性即可指定该Bean
的父Bean
, parent
属性指定该Bean
所继承的父Bean
的id
.
父Bean中无法被继承的属性
子Bean
无法从父Bean
继承如下属性:depends-on
、 autowire
、 singleton
、 scope
、lazy-init
,这些属性将总是从子Bean
定义中获得,或采用默认值
修改上面的配置文件如下,增加了子Bean
定义。
1 |
|
在配置文件中chinese
和american Bean
都指定了parent="personTemplate"
属性,这表明这两个Bean
都可从父Bean
那里继承得到配置信息,虽然这两个Bean
都没有直接指定<property>
子元素,但它们会从personTemplate
模板那里继承得到
两个<property>
子元素。也就是说,上面的配置信息实际上相当于如下配置:
1 | <bean id="chinese" class="org.crazyit.app.service.impl.Chinese"> |
使用抽象Bean的好处
不使用抽象Bean
的配置方式不仅会导致配置文件臃肿,而且不利于项目后期的修改、维护,如果有一天项目需要改变chinese
、 american
的name
或所依赖的Axe
对象,程序需要逐个修改每个Bean
的配置信息。
如果使用了抽象Bean
,则只需要修改Bean
模板的配置即可,所有继承该Bean
模板的子Bean
的配置信息都会随之改变。
子类会覆盖父类继承来的相同的配置信息
如果父Bean
(抽象Bean
)指定了class
属性,那么子Bean
连class
属性都可省略,子Bean
将用与父Bean
相同的实现类。除此之外,子Bean
也可覆盖父Bean
的配置信息:当子Bean
拥有和父Bean
相同的配置信息时,将使用以子Bean
的配置信息。
项目结构
1 | E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\abstract |