7.9.1 依赖关系注入之后的行为
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属性指定的方法。