概念
Spring Bean 中所说的作用域,在配置文件中即是“scope”属性。在面向对象程序设计中一般指对象或变量之间的可见范围。而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围
作用域的类型
在Spring 容器当中,一共提供了5种作用域类型,在配置文件中,通过属性scope来设置bean的作用域范围。
- singleton:<bean id="userInfo" class="com.jike.UserInfo" scope="singleton"></bean>
Spring IOC容器中只会存在一个共享的bean实例,而且所有对bean的请求只要id与该bean相匹配,则只会返回bean的同一实例。也就是说当把一个bean的scope属性设置成singleton时,Spring IOC容器只会创建该bean定义的唯一实例,那么这个单一实例会被存储在单例缓存当中,并且所有针对该bean的后续请求以及引用都将返回被缓存的该对象的实例。Singleton是缺省值。
singleton作用域是指在Spring IOC容器中仅存在一个bean实例,bean以单实例的方式存在,单实例模式是重要的设计模式之一,在传统的应用开发当中,我们需要手工的为每一个单实例类编写特定的代码,这种情况下类的业务逻辑代码和模式代码紧密的耦合在一起,而Spring以容器的方式,提供天然的单实例模式功能。无须编写特殊的代码,仅通过配置,就可以实现单实例模式。在一般情况下,无状态或者状态不可变更的类,适合使用单实例模式。不过Spring对此实现了超越,可以对那些非线程安全的对象采用单实例模式。
在默认的情况下,Spring的ApplicationContext容器在启动的时候,自动实例化所有的singleton bean,并缓存于容器中。虽然启动时会花费一些时间,但是带来了两个好处。
1.对bean提前的实例化操作,可以提早的发现一些潜在的配置错误;
2.Bean以缓存的形式保存,当使用到该bean时,就不会再去实例化,这样加快了相关的运行效率。如果用户不需要在容器启动时提前实例化singleton这种bean,可以通过lazy-init属性设置为true来控制,也不是都可以控制,如果某个bean也是用的singleton作用域,并且引用了该bean,则同样是会被提前实例化。
- prototype:<bean id="userInfo" class="com.jike.UserInfo" scope=" prototype "></bean>
会导致在每次对该bean请求的时候,Spring IOC容器都会创建一个新的bean的实例。对于有状态的bean应该使用prototype,而无状态的bean应该使用singleton
prototype作用域是指每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new Bean()的操作。在默认情况下,Spring容器在启动时不实例化prototype的Bean
- request:<bean id="userInfo" class="com.jike.UserInfo" scope=" request "></bean>
针对每次的http请求,Spring容器会根据相关的bean定义创建一个全新的bean实例,而且该实例仅在当前http的request内是有效地,因此可以根据需要放心的更改所创建实例的内部状态,而其它请求中,根据该bean定义创建的实例,将不会看到这些特定域某个请求的状态变换。
- session:<bean id="userInfo" class="com.jike.UserInfo" scope=" session "></bean>
针对某个http session来起作用的。Spring容器会根据该bean的定义创建一个全新的bean实例,且该bean仅在当前http session内是有效的。与request作用域是一样的,你可以根据需要,放心的更改所创建的实例的内部的状态,而别的http session中根据该bean所创建的实例,将不会看到这些特定域http session的状态变化。当http session最终被废弃的时候,在该http session作用域内所创建的bean实例也会被废弃。
- global session:<bean id="userInfo" class="com.jike.UserInfo" scope=“globalSession"></bean>
类似于标准的http session作用域,不过仅仅在于外部应用当中才有意义。