Bean作用域
在每个Spring IoC容器中一个bean定义对应一个对象实例。整个容器中只有该bean的唯一实例
一个bean定义对应多个对象实例。
在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext
情形下有效。
在一个HTTP Session
中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext
情形下有效。
在一个全局的HTTP Session
中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext
情形下有效。
ApplicationContext
实现的默认行为就是在启动时将所有singleton
bean提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext
实例会创建并配置所有的singleton bean。通常情况下这是件好事,因为这样在配置中的任何错误就会即刻被发现(否则的话可能要花几个小时甚至几天)。
有时候这种默认处理可能并不是你想要的。如果你不想让一个singleton bean在ApplicationContext
初始化时被提前实例化,那么可以将bean设置为延迟实例化。一个延迟初始化bean将告诉IoC 容器是在启动时还是在第一次被用到时实例化。
在XML配置文件中,延迟初始化将通过<bean/>
元素中的lazy-init
属性来进行控制。例如:
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/> <bean name="not.lazy" class="com.foo.AnotherBean"/>
当ApplicationContext
实现加载上述配置时,设置为lazy
的bean将不会在ApplicationContext
启动时提前被实例化,而not.lazy
却会被提前实例化。
需要说明的是,如果一个bean被设置为延迟初始化,而另一个非延迟初始化的singleton bean依赖于它,那么当ApplicationContext
提前实例化singleton bean时,它必须也确保所有上述singleton 依赖bean也被预先初始化,当然也包括设置为延迟实例化的bean。因此,如果Ioc容器在启动的时候创建了那些设置为延迟实例化的bean的实例,你也不要觉得奇怪,因为那些延迟初始化的bean可能在配置的某个地方被注入到了一个非延迟初始化singleton bean里面。
在容器层次上通过在<beans/>
元素上使用'default-lazy-init'
属性来控制延迟初始化也是可能的。如下面的配置:
prototype 则是容器启动时 实例化对象
Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()
方法)时都会创建一个新的bean实例。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责:容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法。但对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被prototype作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,该处理器持有要被清除的bean的引用。)
来源:https://www.cnblogs.com/liaomin416100569/archive/2009/12/02/9332123.html