Spring中单例多例及懒加载机制

1.单例和多例

Spring容器管理的bean在默认情况下是单例的,也即,一个bean只会创建一个对象,存在内置 map中,之后无论获取多少次该bean,都返回同一个对象。

Spring默认采用单例方式,减少了对象的创建,从而减少了内存的消耗。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        scope:
            singleton - 单例,默认值
                容器创建时创建对象并保存到容器内部
                自后无论获取多少次,都是从容器内部中获取该对象返回,所以得到的将是同一个对象
                直到容器被销毁时,对象被移除出容器
            prototype - 多例
                容器初始化时,不会创建多例对象,只是将多例bean信息保存
                每次获取多例对象时,都会根据保存的bean信息创建新的对象并返回
                且这些对象不会保存到容器内部的map中
                对象何时被销毁完全取决于用户程序本身
    -->
    <bean id="cart" class="cn.ww.domain.Cart" scope="prototype"/>
</beans>

 

但是在实际开发中是存在多例的需求的(如购物车,用户的订单等),Spring也提供了选项可以将bean设置为多例模式。

bean在单例模式下的生命周期:

bean在单例模式下,spring容器启动时解析xml发现该bean标签后,直接创建该bean的对象存入内部map中保存,此后无论调用多少次getBean()获取该bean都是从map中获取该对象返回,一直是一个对象。此对象一直被Spring容器持有,直到容器退出时,随着容器的退出对象被销毁。

bean在多例模式下的生命周期:

bean在多例模式下,spring容器启动时解析xml发现该bean标签后,只是将该bean进行管理,并不会创建对象,此后每次使用 getBean()获取该bean时,spring都会重新创建该对象返回,每次都是一个新的对象这个对象spring容器并不会持有,什么销毁取决于使用该对象的用户自己什么时候销毁该对象。

注:通过断点调试模式 ,可以观察spring单例和多例的bean执行构造的过程

scope="singleton" 时,调试结果如下,容器创建时就创建了对象

                

               当 scope="prototype" 时,调试结果如下,获取bean时对象才创建

                

2. 懒加载机制

Spring默认会在容器初始化的过程中,解析xml,并将单例的bean创建并保存到map中,这样的机制在bean比较少时问题不大,但一旦bean非常多时,spring需要在启动的过程中花费大量的时间来创建bean 花费大量的空间存储bean,导致程序启动越来越慢,占用内存越来越大,但这些bean可能很久都用不上,这种在启动时在时间和空间上的浪费显得非常的不值得。

所以Spring提供了懒加载机制。所谓的懒加载机制就是可以规定指定的bean不在启动时立即创建,而是在后续第一次用到时才创建,从而减轻在启动过程中对时间和内存的消耗。

懒加载机制只对单例bean有作用,对于多例bean设置懒加载没有意义

懒加载只是延后了对象创建的时机,对象仍然是单例的。

懒加载的配置方式:

为指定bean配置懒加载

    1

    2

    3

    4

    5

    6

    7

    8

    9

   10

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.springframework.org/schema/beans

        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"

        >

        

        <bean id="cart" class="cn.tedu.beans.Cart" lazy-init="true"></bean>

        

</beans>

为全局配置懒加载(当需要设置的懒加载的bean过多时,不用一个个的去设置可以设置default-lazy-init="true",不设置默认为false)

    1

    2

    3

    4

    5

    6

    7

    8

    9

   10

   11

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.springframework.org/schema/beans

        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"

        default-lazy-init="true"

        >

        

        <bean id="cart" class="cn.tedu.beans.Cart"></bean>

        

</beans>

**如果同时设定全局和指定bean的懒加载机制,且配置不相同,则对于该bean局部配置覆盖全局配置。

 注:通过断点调试,可以验证懒加载机制的执行过程

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章