Spring Core 官方文档阅读笔记(二)

  1. 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的生命周期内有一个实例
  1. singleton
    spring的singleton与单例模式有一定的区别,具体如下:
  • spring的singleton是指在单个spring IOC容器内只有一个实例,而单例模式的单例是指在JVM范围内只有一个实例。如果在一个工程内创建多个spring IOC容器,即使Bean的Scope被定义为singleton,通过不同容器获取到的实例也不同。
  1. prototype
    若将Bean的scope设定为prototype,则在每次请求特定Bean的时候都会创建一个实例,即bean被注入到另一个bean,或者通过getBean()来获取时。
    通常,对有状态的Bean应该优先考虑prototype,而对无状态的Bean则考虑使用singleton。
    prototype与其他scope类型相比,spring容器不会管理其完整的生命周期。对所有的scope类型,spring都会调用生命周期的初始化回调方法,但是在prototype类型下,不会调用生命周期的销毁回调方法,所以客户端代码必须自行回收bean所持有的资源。

  2. application
    application和singleton有些相似,application是在单个ServletContext内只有一个实例,而singleton是在单个ApplicationContext内只有一个实例。

  3. 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>
  1. 自定义scope
    可以自定义scope,甚至可以重新定义现有的scope,但是无法覆盖内置的singleton和prototype。
    实现方法可参照SimpleThreadScope

  2. 生命周期回调
    spring管理的Bean的生命周期可以通过实现InitializingBean和DisposableBean来交互。也可以通过实现Lifycycle接口来交互。
    InitializingBean的afterPropertiesSet和DisposableBean的destory。

  3. 默认初始化和销毁方法

<beans default-init-method="init" default-destory-method="destory">
    <bean id="example" class="example.Example">
        <property name="property" ref="xxx"/>
    </bean>
</beans>
  1. 控制生命周期的方法的执行顺序
    当前有三种方法可以与bean的生命周期进行交互:
    InitializingBean和DisposableBean
    定制init和destory方法
    @PostConstruct和@PreDestory

若为同一个Bean配置了多个交互方式,则按照如下顺序执行:
@PostConstruct和@PreDestory --> InitializingBean和DisposableBean --> 定制init和destory方法(xml配置里的init-method和destory-method)

  1. 在非web应用中优雅的关闭Spring IOC容器
    调用ConfigurableApplicationContext的registerShutdownHook()方法来关闭容器,可以确保资源的释放。
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
context.registerShutdownHook();
posted @ 2020-04-27 08:46  kuromaru  阅读(159)  评论(0)    收藏  举报