IOC容器中对象的作用域

/ Spring / 没有评论 / 342浏览

在IOC容器中我们可以使用scope属性来设置对象的作用域。在IOC容器中主要为对象提供了5种类型的作用域。我们分别看看它们具体的区别。

在IOC容器中只存在一个实例,也就是通过singleton作用域创建的对象是单例的。

<bean scope="singleton" id="user" class="com.jilinwula.spring.User" p:username="admin" p:password="jilinwula" p:nickname="吉林乌拉"/>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user1 = applicationContext.getBean("user", User.class);
User user2 = applicationContext.getBean("user", User.class);
System.out.println(user1);
System.out.println(user2);
}
com.jilinwula.spring.User@4b1c1ea0
com.jilinwula.spring.User@4b1c1ea0

这两个对象的内存地址相同,这就说明了当前对象确实是一个单例对象了。

第次从IOC容器中获取对象时,都返回一个新对象。

<bean scope="prototype" id="user" class="com.jilinwula.spring.User" p:username="admin" p:password="jilinwula" p:nickname="吉林乌拉"/>
com.jilinwula.spring.User@1e965684
com.jilinwula.spring.User@4d95d2a2

每次HTTP请求都会创建一个新的对象,当请求结束时则会自动销毁这个对象。该作用域只针对Web环境中使用。

同一个HTTP Session共享一个对象,不同的HTTP Session使用不同的对象,当这个Session结束时销毁这个对象。该作用域也是只针对Web环境中使用的。

同一个全局Session共享一个对象,该作用域也是只针对Web环境中使用的。

我们知道当我们使用ApplicationContext接口启动IOC容器时,会自动的实例化所有singleton作用域的对象,这一点和BeanFactory不同。虽然这么做IOC容器启动时会很耗时,但是这样做也有这样做的好处。就是初始化后的对象会被存储在IOC容器的缓存中,这样当我们使用对象时,就不用在实例化对象了,从而提高了程序的运行效率。另一个好处就是可以帮助我们早点发现问题,如果我们配置的对象有问题时,则会直接在启动阶段抛出异常,而不是在程序的运行阶段。当然每种方式都有每种方式的好处与弊端,如果我们不想在启动时实例化对象,那么我们可以直接用spring为我们提供的lazy-init属性延迟我们对象的实例化。也就是说当把lazy-init属性值设置为true,然后通过ApplicationContext接口启动IOC容器时,当前对象是不会在启动阶段实例化的,而是在运行时才会实例化当前对象。

<bean lazy-init="true" id="user" class="com.jilinwula.spring.User" p:username="admin" p:password="jilinwula" p:nickname="吉林乌拉"/>