Spring 核心——Bean 的定义与控制,linuxshell 脚本教程
通常情况下,所有的?singleton?类型的 Bean 都会在容器创建后进行初始化,简单的说就是启动 Jvm 就开始创建(实际上是创建 ApplicationContext 的某个实现类实例之后)。
IoC 支持所有的?singleton?Bean 在使用时再加载,这样做的好处是可以大大节省初始化的时间。但是如果你的应用对启动时间的长短并不敏感,建议让所有的?singleton?都启动时加载。这样可以在启动时就发现一些问题,而不是在运行很久直到使用时才由用户去触发这个问题。或者可以根据场景来使用决定是否延迟,例如开发时使用延迟加载,而在集成测试或上生产时关闭。
可以设置全局延迟加载,也可以设置某个 Bean 延迟加载:
<beans default-lazy-init="true">
</beans>
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>
<bean name="not.lazy" class="com.foo.AnotherBean"/>
需要注意的是,在设置某个单独的 Bean 延迟加载时,如果有某个没有延迟加载的 Bean 要依赖他,那实际上也会在初始化的时候就加载。
还要强调一下,这里的“加载”仅仅是为了表示一个类被 Ioc 创造并放置容器中,和 classLoad 方法将 class 文件中的字节码加载到方法区的加载是两个概念。
延迟加载在设计模式上是单例模式一种延伸,通常也被称为懒汉模式。单例通常有双重锁+volatile、静态类和枚举三种方式实现。在Effective?Java一书中对三种模式都有深入的解析。而对于 Spring 容器而言,枚举的方式肯定不好用了,静态类由于属于自身代码级别应该也不会用,所以双重锁的实现方式较为可信。不过我没去看过源码,仅属于猜测。
生命周期方法
一个 Bean 的创建、使用再到最后销毁称为"Bean 的生命周期"。Spring 框架为 Bean 的生命周期各个阶段提供了多种回掉方法来处理各种状态或者数据。
初始化方法
当一个 Bean 完成初始化并注入各项参数之后,初始化回掉方法会被调用,简单的说就是完成创建之后会被调用。实现初始化回调方法有 2 个路径:1.继承 org.springframework.beans.factory.InitializingBean 接口,然后实现 afterPropertiesSet 方法。2.在 Bean 的 XML 配置上使用 init-method 属性来制定要调用的初始化:
继承实现:
<bean id="a" class="x.y.A" />
package x.y;
public class A implements InitializingBean {
public void afterPropertiesSet(){
// init
}
}
配置实现:
<bean id="a" class="x.y.A" init-method="init" />
package x.y;
public class A {
public void init(){}
}
2 种方法都等效,实际使用是我们应该使用哪一种方法呢?
InitializingBean 是 Spring 早期实现的一个生命周期回调方法。但是在 JCP 推出 JSR-250 和JSR-330规范之后,Spring 的大神们开始意识到基于元编程思想和配置手段来实现非侵入式框架(Not Coupled)才是正道。所以现在都是推荐使用配置文件和 JSR-250 的 @PostConstruct(关于各种 Annotation 的使用请关注后续的文章)。现在依然保留 InitializingBean 应该是考虑到兼容问题。
销毁方法
与创建方法相对应的是销毁方法。当一个类将要被销毁之前,对应的销毁回调方法会被调用。销毁方法也有一个继承实现和配置+注解实现:
继承实现:
<bean id="a" class="x.y.A" />
package x.y;
public class A implements DisposableBean {
publi
c void destroy(){
// 销毁资源
}
}
配置实现:
<bean id="a" class="x.y.A" destroy-method="cleanUp" />
package x.y;
public class A {
public void cleanUp(){
// 销毁资源
}
}
依然建议销毁手段也使用配置或 @PreDestroy 来设定销毁方法。
全局配置初始化与销毁方法
IoC 容器还提供了全局配置初始化与销毁方法的配置:
评论