Spring框架提供了许多接口,您可以使用这些接口自定义bean的性质。 本节将它们归类如下:
- 生命周期回调
- ApplicationContextAware
和
BeanNameAware - 其他r
Aware
接口 -
(1)生命周期回调
初始化回调
org.springframework.beans.factory.InitializingBean.InitializingBean
的接口允许bean在容器设置了bean上的所有必要属性之后执行【初始化工作】。【InitializingBean】接口指定了一个方法: -
void afterPropertiesSet() throws Exception;
我们建议您不要使用【InitializingBean】接口,因为这将你的代码与Spring的代码耦合在一起。 我们更推荐使用【@PostConstruct】注解或指定POJO初始化方法。
在基于xml的配置元数据的情况下,您可以使用【init-method】属性指定具有void无参数签名的方法的名称。 在Java配置中,您可以使用【@Bean】的【initMethod】属性。可以看看下面的例子:
-
<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
(2)销毁回调
实现
org.springframework.beans.factory.DisposableBean
接口可以让bean在管理它的容器被销毁时获得回调。 ' DisposableBean '接口指定了一个方法:
void destroy() throws Exception;
同样,我们并不建议您使用【DisposableBean】回调接口,因为我们没有必要将自己的代码与Spring耦合在一起。 另外,我们建议使用【@PreDestroy】注解或指定beanDifination支持的销毁方法。 对于基于xml的配置元数据,您可以在<bean/>
上使用' destroy-method '属性。 在Java配置中,您可以使用“@Bean”的【destroyMethod】属性。如下所示:
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
public class ExampleBean {
public void cleanup() {
// do some destruction work (like releasing pooled connections)
}
}
(3)默认初始化和销毁方法
当我们不使用spring特有的InitializingBean和disapablebean回调接口进行初始化和销毁时,我们通常会编写名为【init()】、 【initialize()】、 【dispose()】等的方法。 理想情况下,这种生命周期回调方法的名称在项目中应该是标准化的(项目经理规定了都必须这么写),以便所有开发人员使用相同的方法名称,并确保一致性。
您可以配置统一的bean的初始化和销毁方法。 这意味着,作为应用程序开发人员,您可以仅仅声明一个名为【init()】的初始化方法即可,而不必为每个beanDifination配置一个【init-method=“init】属性。
假设你的初始化回调方法名为“init()”,你的destroy回调方法名为“destroy()”。 你的类就像下面这个例子中的类:
public class DefaultBlogService implements BlogService {
private BlogDao blogDao;
public void setBlogDao(BlogDao blogDao) {
this.blogDao = blogDao;
}
// this is (unsurprisingly) the initialization callback method
public void init() {
if (this.blogDao == null) {
throw new IllegalStateException("The [blogDao] property must be set.");
}
}
}
然后,您可以在bean中使用该类,类似如下:
<beans default-init-method="init">
<bean id="blogService" class="com.something.DefaultBlogService">
<property name="blogDao" ref="blogDao" />
</bean>
</beans>
顶层<beans/>
元素属性上的【default-init-method】属性导致Spring IoC容器将bean类上的一个名为【init】的方法识别为初始化方法回调。 在创建和组装bean时,如果bean类有这样的方法,就会在适当的时候调用它。
如果现有的bean类已经有按约定命名的回调方法,那么您可以通过使用<bean/>
本身的【init-method】和【destroy-method】属性指定对应方法来覆盖默认值
(4)总结
从Spring 2.5开始,你有三个选项来控制bean的生命周期行为:
InitializingBean
和DisposableBean
和DisposableBean
回调接口- 自定义
init()
和destroy()
方法 @PostConstruct
和@PreDestroy
您可以组合这些机制来控制给定的bean。
为同一个bean配置的多个生命周期机制(具有不同的初始化方法),调用顺序如下:
- 用“@PostConstruct”注解的方法
afterPropertiesSet()
由InitializingBean
回调接口- 自定义配置的init()方法
Destroy方法的调用顺序相同:
- 用
@PreDestroy
注解的方法 destroy()
由DisposableBean
回调接口定义- 自定义配置的
destroy()
方法
#(5)ApplicationContextAware
和 BeanNameAware
下面显示了“ApplicationContextAware”接口的定义:
public interface ApplicationContextAware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
因此,bean可以通过【ApplicationContextAware】接口,以编程方式【操作】创建它们的【ApplicationContext】。 其中一个用途是对其他bean进行编程检索, 有时这种能力是有用的。 但是,一般来说,您应该【避免使用它】,因为它将代码与Spring耦合在一起,而不遵循控制反转(Inversion of Control)风格,在这种风格中,协作者作为属性提供给bean。 ApplicationContext的其他方法提供了对文件资源的访问、发布应用程序事件和访问MessageSource。
当ApplicationContext创建一个实现了BeanNameAware接口的类时。 他提供了对其关联对象定义中定义的名称的引用。 下面的例子显示了BeanNameAware接口的定义:
public interface BeanNameAware {
void setBeanName(String name) throws BeansException;
}
回调在填充普通bean属性之后,但在初始化回调(如“InitializingBean.afterPropertiesSet()”或自定义初始化方法之前调用。
总结:实现了aware相关的接口,ioc容器不在遵循ioc风格,意思就是不在遵循按需初始化并注入依赖,而是在统一的地方统一注入,这个在源码中有所体现,后边的内容会涉及。