spring bean的scope属性

spring中bean的scope属性,有如下5种类型:

  1. singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例
  2. prototype表示每次获得bean都会生成一个新的对象,每次请求(每次使用)创建新的实例,destroy方式不生效.
  3. request表示在一次http请求内有效(只适用于web应用)
  4. session表示在一个用户会话内有效(只适用于web应用)
  5. globalSession表示在全局会话内有效(只适用于web应用)

在多数情况,我们只会使用singletonprototype两种scope,如果在spring配置文件内未指定scope属性,默认为singleton

下面我们用一个示例来说明singleton和prototype两种scope的区别。

添加java类Person,Person的内容如下:

public class Person {
	private int id;
	private String name;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
Person类是一个POJO类,我们不需要他做任何事情,只是为了证明prototype和singleton两种scope的异同之处.
我们还需要一个App类,他的代码如下:
public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext appContext = new ClassPathXmlApplicationContext("/spring.xml");
        Person p1 = appContext.getBean(Person.class);
        System.out.println("p1's identityHashCode is " + System.identityHashCode(p1));
        
        Person p2 = appContext.getBean(Person.class);
        System.out.println("p2's identityHashCode is " + System.identityHashCode(p2));
        
    }
}

在App类中的main方法中,首先我们初始化了ApplicationContext的实例,然后分别获得两次Person bean的实例p1,p2并分别输出其identityHashCode,如果两个对象是同一个对象,那么他们的identityHashCode应该是 一致的。

添加source folder:src/main/conf,并新建spring配置文件spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">	
	<bean class="cn.outofmemory.spring.Person">
		<property name="id" value="1"/>
		<property name="name" value="Jim"/>
	</bean>	
</beans>

在此配置文件中我们定义了Person bean,没有指定其scope,这时候bean的scope为默认的singleton,也就是单例,此时App类的输出应该是两个相同的identityHashcode,我们运行程序看输出的结果:
p1's identityHashCode is 23954271
p2's identityHashCode is 23954271
可以看到p1和p2是完全相同的,我们再修改spring.xml配置文件,将Person bean的scope修改为prototype:
<bean class="cn.outofmemory.spring.Person" scope="prototype">
		<property name="id" value="1"/>
		<property name="name" value="Jim"/>
	</bean>

再次运行程序,输出结果如下:
p1's identityHashCode is 23954271
p2's identityHashCode is 13359324


可以看到p1和p2是两个不同的值,这说明scope是prototype的情况下,同一个bean定义会返回不同的对象。

我们也可以通过Scope注解来指定java bean的scope,我们给Person类添加如下注解:

@Component
@Scope("prototype")
public class Person {
....省略
}

@Component注解告诉spring,要加载此类,Scope注解bean的scope是prototype。

我们修改spring.xml配置文件,使用context:component-scan节点,让spring通过注解加载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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">	
	 <context:component-scan base-package="cn.outofmemory.spring"></context:component-scan>	
</beans>

再次运行程序,将输出:
p1's identityHashCode is 33212498
p2's identityHashCode is 24480977

可以看到使用Scope注解指定prototype scope后,两个Person对象是两个不同的对象。

示例2:
UnitTestBase 
public class UnitTestBase {
    
    private ClassPathXmlApplicationContext context;
    
    private String springXmlpath;
    
    public UnitTestBase() {}
    
    public UnitTestBase(String springXmlpath) {
        this.springXmlpath = springXmlpath;
    }
    
    @Before
    public void before() {
        if (StringUtils.isEmpty(springXmlpath)) {
            springXmlpath = "classpath*:spring-*.xml";
        }
        try {
            context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
            context.start();
       //context
就是所谓的容器
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }
    
    @After
    public void after() {
        context.destroy();
    }
    
    @SuppressWarnings("unchecked")
    protected <T extends Object> T getBean(String beanId) {
        try {
            return (T)context.getBean(beanId);
        } catch (BeansException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    protected <T extends Object> T getBean(Class<T> clazz) {
        try {
            return context.getBean(clazz);
        } catch (BeansException e) {
            e.printStackTrace();
            return null;
        }
    }
}
TestBeanScope 
public class TestBeanScope extends UnitTestBase {
    
    public TestBeanScope() {
        super("classpath*:spring-beanscope.xml");
    }
    
    @Test
    public void testSay() {
        BeanScope beanScope = super.getBean("beanScope");
        beanScope.say();
        
        BeanScope beanScope2 = super.getBean("beanScope");
        beanScope2.say();
    }
    
    @Test
    public void testSay2() {
        BeanScope beanScope  = super.getBean("beanScope");
        beanScope.say();
    }
}
BeanScope 
public class BeanScope {
    
    public void say() {
        System.out.println("BeanScope say : " + this.hashCode());
    }
    
}

配置文件 spring-beanscope.xml
 <?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.xsd" >
        
        <bean id="beanScope" class="com.imooc.bean.BeanScope" scope="singleton"></bean>
        
 </beans>

1.当运行 testSay 方法时结果为:
BeanScope say : 13480046
BeanScope say : 13480046
2.当运行TestBeanScope 结果为:
BeanScope say : 29420695
BeanScope say : 29420695
BeanScope say : 19480755

 修改配置文件 spring-beanscope.xml
<?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.xsd" >
        
        <bean id="beanScope" class="com.imooc.bean.BeanScope" scope="prototype"></bean>
        
 </beans>
prototype表示每次获得bean都会生成一个新的对象,每次请求(每次使用)创建新的实例,destroy方式不生效.
1.当运行 testSay 方法时结果为:
BeanScope say : 13480046
BeanScope say : 33168310

2.当运行TestBeanScope 类时结果为:
BeanScope say : 32278793
BeanScope say : 1623405
BeanScope say : 22293109
 
posted @ 2016-01-23 15:09  我i编程  阅读(492)  评论(0编辑  收藏  举报