在Spring中,bean对象可以有多种作用域
以下测试中所需的文件:
PersonService接口
package org.spring.service;
public interface PersonService {
public void showMessage();
}
PersonService的实现类PersonServiceBean
package org.spring.service.impl;
import org.spring.service.PersonService;
public class PersonServiceBean implements PersonService {
public PersonServiceBean() {
System.out.println("实例化...");
}
public void showMessage() {
System.out.println("Hello Spring World!");
}
}
1、singletion 默认的,每个IOC容器只创建一个Bean实例
配置文件:
<?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-2.5.xsd"> <bean id="personServiceBean" class="org.spring.service.impl.PersonServiceBean" scope="singleton" /> </beans>
测试类:
package org.spring.junit;
import org.junit.Test;
import org.spring.service.PersonService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");
PersonService personService1 = (PersonService) ctx
.getBean("personServiceBean");
PersonService personService2 = (PersonService) ctx
.getBean("personServiceBean");
System.out.println(personService1 == personService2);
}
}
控制台打印结果为实例化...与true,说明是同一个bean
默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:
<?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-2.5.xsd"> <bean id="personServiceBean" class="org.spring.service.impl.PersonServiceBean" scope="singleton" lazy-init="true" /> </beans>
测试类
package org.spring.junit;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");
}
}
此时控制台什么都没有打印,测试文件修改如下之后
package org.spring.junit;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");
ctx.getBean("personServiceBean");
}
}
控制台打印出了实例化...字样,说明只有在获取bean的时候才会初始化bean,也称延迟加载
如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:
<?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-2.5.xsd" default-lazy-init="true"> <bean id="personServiceBean" class="org.spring.service.impl.PersonServiceBean" scope="singleton" /> </beans>
一般情况下,我们希望在容器启动的时候就初始化配置文件中的bean,所以一般不配置成延迟加载
2、prototype每次从容器获取bean都是新的对象
此时配置文件如下
<?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-2.5.xsd"> <bean id="personServiceBean" class="org.spring.service.impl.PersonServiceBean" scope="prototype" /> </beans>
测试类
package org.spring.junit;
import org.junit.Test;
import org.spring.service.PersonService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");
PersonService personService1 = (PersonService) ctx
.getBean("personServiceBean");
PersonService personService2 = (PersonService) ctx
.getBean("personServiceBean");
System.out.println(personService1 == personService2);
}
}
控制台打印结果为
实例化...
实例化...
false
可以看到打印出两个实例化...,说明bean被实例化了两次,从容器获取的bean是新的对象
3、request每次http请求创建一个实例
4、session每次会话创建一个实例
5、globalsession每个全局Http请求创建一个实例