Spring Core 官方文档阅读笔记(二)
- Bean Scopes
Spring托管的Bean的Scope有6种,如下:
| Scope | Description |
|---|---|
| singleton | 每个Spring IOC容器内只有一个实例,可以使用@Scope("singleton")设置 |
| prototype | 可以有任意数量的实例,可以使用@Scope("prototype")设置 |
| request | 每个HTTP请求的生命周期内有一个实例,即每个请求都有自己的Bean实例,可以使用@RequeseScope来设置 |
| session | 每个HTTP Session的生命周期内有一个实例,可以使用@SessionScope来设置 |
| application | 每个ServletContext的生命周期内有一个实例,可以使用@ApplicationScope来设置 |
| websocket | 每个webSocket的生命周期内有一个实例 |
- singleton
spring的singleton与单例模式有一定的区别,具体如下:
- spring的singleton是指在单个spring IOC容器内只有一个实例,而单例模式的单例是指在JVM范围内只有一个实例。如果在一个工程内创建多个spring IOC容器,即使Bean的Scope被定义为singleton,通过不同容器获取到的实例也不同。
-
prototype
若将Bean的scope设定为prototype,则在每次请求特定Bean的时候都会创建一个实例,即bean被注入到另一个bean,或者通过getBean()来获取时。
通常,对有状态的Bean应该优先考虑prototype,而对无状态的Bean则考虑使用singleton。
prototype与其他scope类型相比,spring容器不会管理其完整的生命周期。对所有的scope类型,spring都会调用生命周期的初始化回调方法,但是在prototype类型下,不会调用生命周期的销毁回调方法,所以客户端代码必须自行回收bean所持有的资源。 -
application
application和singleton有些相似,application是在单个ServletContext内只有一个实例,而singleton是在单个ApplicationContext内只有一个实例。 -
aop:scoped-proxy/
当一个scope为singleton的bean内依赖一个scope为prototype的bean时,除了Spring Core 官方文档阅读笔记(一)中的12、13、14所指出的方法外,还可以使用aop:scoped-proxy/来解决,如下:
原型bean:
public class PrototypeBean {
private Long timeMilis;
public PrototypeBean() {
this.timeMilis = new Date().getTime();
}
public void printTime() {
System.out.println("timeMils:" + timeMilis);
}
}
单例bean:
public class SingletonBean {
private PrototypeBean prototypeBean;
public void setPrototypeBean(PrototypeBean prototypeBean) {
this.prototypeBean = prototypeBean;
}
public void printTime() {
prototypeBean.printTime();
}
}
<bean id="prototypeBean" class="example.PrototypeBean" scope="prototype">
<aop:scoped-proxy/>
</bean>
<bean id="singletonBean" class="example.SingletonBean">
<property name="prototypeBean">
<ref bean="prototypeBean"/>
</property>
</bean>
或
<bean id="prototypeBean" class="example.PrototypeBean" scope="prototype">
<!-- 不使用CGLIB,使用基于JDK接口的标准代理 -->
<aop:scoped-proxy proxy-target-class="false"/>
</bean>
<bean id="singletonBean" class="example.SingletonBean">
<property name="prototypeBean" ref="prototypeBean"/>
</bean>
-
自定义scope
可以自定义scope,甚至可以重新定义现有的scope,但是无法覆盖内置的singleton和prototype。
实现方法可参照SimpleThreadScope -
生命周期回调
spring管理的Bean的生命周期可以通过实现InitializingBean和DisposableBean来交互。也可以通过实现Lifycycle接口来交互。
InitializingBean的afterPropertiesSet和DisposableBean的destory。 -
默认初始化和销毁方法
<beans default-init-method="init" default-destory-method="destory">
<bean id="example" class="example.Example">
<property name="property" ref="xxx"/>
</bean>
</beans>
- 控制生命周期的方法的执行顺序
当前有三种方法可以与bean的生命周期进行交互:
InitializingBean和DisposableBean
定制init和destory方法
@PostConstruct和@PreDestory
若为同一个Bean配置了多个交互方式,则按照如下顺序执行:
@PostConstruct和@PreDestory --> InitializingBean和DisposableBean --> 定制init和destory方法(xml配置里的init-method和destory-method)
- 在非web应用中优雅的关闭Spring IOC容器
调用ConfigurableApplicationContext的registerShutdownHook()方法来关闭容器,可以确保资源的释放。
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
context.registerShutdownHook();

浙公网安备 33010602011771号