bean的作用域,其实就是设置创建 bean 的实例是属于单实例,还是多实例。
1. 默认单实例
默认情况下,创建的 bean 是单实例对象。
比如,用之前的代码为例:
@Test public void testCollection2() { ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); Book book = context.getBean("book", Book.class); Book book2 = context.getBean("book", Book.class); System.out.println(book); System.out.println(book2); }
在测试方法中,创建了 2 个 Book 类型的实例 book 和 book2,默认情况下应该是单实例,打印出来的地址应该一致。
com.pingguo.spring5.collectiontype.Book@4ae82894 com.pingguo.spring5.collectiontype.Book@4ae82894 Process finished with exit code 0
地址一致。
2. 设置多实例
在配置文件中的 bean 标签里,有一个属性 scope
是用来设置单实例和多实例的。
scope 有多个值:
- singleton:也是默认值,表示单实例对象。
- prototype:表示多实例对象。
- request:每次 http 请求都会创建一个新的 bean,仅适用于 WebApplicationContext 环境。
- session:同一个 http session 共享一个 bean,不同的 session 使用不同的 bean,仅适用于 WebApplicationContext 环境。
而最常用的有 2 个:singleton 和 prototype。
现在把上述的示例代码改成多实例的,那么配置文件中增加 scope="prototype"
:
<bean id="book" class="com.pingguo.spring5.collectiontype.Book" scope="prototype"> <property name="list" ref="bookList"></property> </bean>
再次运行测试方法:
com.pingguo.spring5.collectiontype.Book@543788f3 com.pingguo.spring5.collectiontype.Book@6d3af739 Process finished with exit code 0
可以看到,2个对象地址不同。
此外,singleton 和 prototype 还有 1 个区别需要注意:
- scope 值为 singleton :加载 spring 配置文件的时候,就会创建单例对象。
- scope 值为 prototype :加载配置文件时候不创建,而是在调用 getBean 方法时候创建多个实例对象。