7.9.1 依赖关系注入之后的行为
Spring
提供两种方式在Bean
全部属性设置成功后执行特定行为。
- 使用
init-method
属性 - 实现
InitializingBean
接口
第一种方式:使用init-method
属性指定某个方法应在Bean
全部依赖关系设置结束后自动执行。使用这种方式不需要将代码与Spring
的接口耦合在一起,代码污染小。
第二种方式:也可达到同样的效果,就是让Bean
类实现InitializingBean
接口,该接口提供一个方法:void afterPropertiesSet() throws Exception
。Spring
容器会在为该Bean
注入依赖关系之后,调用该Bean
所实现的afterPropertiesSet()
方法。
程序示例
项目结构
1 | E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\lifecycle-init |
Chinese.java
下面是该Bean
实现类的代码。
1 | package org.crazyit.app.service.impl; |
上面程序中的粗体字代码定义了一个普通的init
方法,实际上这个方法的方法名是任意的,并不定是init0, Spring
也不会对这个init()
方法进行任何特别的处理。只是配置文件使用init-method
属性指定该方法是一个”生命周期方法”。
增加init-method="init"
来指定init()
方法应在Bean
的全部属性设置结束后自动执行
,如果它不实现InitializingBean
接口,上面的Chinese
类没有实现任何Spring
的接口,只是增加一个普通的init()
方法,它依然是一个普通的Java
文件,没有代码污染。
实现Initializingbean
接口的Bean
类必须实现afterPropertiesSet()
方法。
除此之外,该实现类还实现了Spring
提供的BeanNameAware
、 ApplicationContextAware
接口,并实现了这两个接口中定义的setBeanName()
、 setApplicationContext()
方法,这样即可观察到Spring
容器在创建Bean
实例、调用setter
方法执行依赖注入、执行完setBeanName()
、 setApplicationContext()
方法之后,自动执行Bean
的初始化行为(包括init-method
指定的方法和afterPropertiesSet()
方法)。
beans.xml
下面的配置文件指定org.crazyit.app.service.impl.Chinese
的init()
方法是一个生命周期方法。
1 |
|
运行结果
1 | Spring实例化依赖bean:SteelAxe实例... |
代码分析
通过上面的执行结果可以看出,当Spring
将steelAxe
注入chinese bean
(即完成依赖注入)之后,以及调用了setBeanName()
、 setApplicationContext()
方法之后, Spring
先调用该Bean
的afterPropertiesSet()
方法进行初始化,再调用init-method
属性所指定的方法进行初始化。
对于实现InitializingBean
接口的Bean
,无须使用init-method
属性来指定初始化方法,配置该Bean
实例与配置普通Bean
实例完全一样, Spring
容器会自动检测Bean
实例是否实现了特定生命周期接口,并由此决定是否需要执行生命周期方法。
不推荐实现InitializingBean接口方式
如果某个Bean
类实现了InitializingBean
接口,当该Bean
的所有依赖关系被设置完成后, Spring
容器会自动调用该Bean
实例的afterPropertiesSet()
方法。其执行结果与采用init-method
属性指定生命周期方法几乎一样。但实现InitializingBean
接口污染了代码,是侵入式设计,因此不推荐采用。
既使用init-method属性又实现InitializingBean接口时
如果既采用init-method
属性指定初始化方法,又实现InitializingBean
接口来指定初始化方法, Spring
容器会执行两个初始化方法:先执行InitializingBean
接口中定义的方法,然后执行init-method
属性指定的方法。
原文链接: 7.9.1 依赖关系注入之后的行为