Spring:Bean作用域

Spring Bean的作用域是指Spring容器在创建Bean对象的时候,相对于其他Bean对象的可见范围

一共有五种可设置的作用域

作用域 描述
singleton

在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,默认值

prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()
request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境
global-session 一般用于Portlet应用环境,改作用于仅适用于WebApplicationContext环境

而作用域的选项在XML文件里通过scope字段来设置,这里主要看前两项

singleton:当一个bean的作用域是singleton,在Spring容器里只会有唯一一个共享的bean对象,只要bean id一样,返回的都是同一个bean实例对象

prototype:当一个bean的作用域是prototype,一个bean id会对应多个bean实例对象,每次实例化都是一个新的bean实例对象

 

定义一个Hello类

package com.lihuia.singleton;

/**
* Copyright (C), 2014-2018, lihuia.com
* FileName: Hello
* Author: lihui
* Date: 2018/6/24
*/

public class Hello {
private String message;

public void setMessage(String message) {
this.message = message;
}

public String getMessage() {
return message;
}
}

实例化

package com.lihuia.singleton;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* Copyright (C), 2014-2018, lihuia.com
* FileName: Main
* Author: lihui
* Date: 2018/6/24
*/

public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Hello helloA = (Hello)context.getBean("hello");
Hello helloB = (Hello)context.getBean("hello");
System.out.println(helloA == helloB);

}
}

创建一个配置XML,作用域为singleton

<?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="hello" class="com.lihuia.singleton.Hello"
scope="singleton"></bean>
</beans>

此时由于是单例作用域,只要是实例化bean的请求中,id和XML里bean一致,都会返回同一个缓存的bean单例实例,因此这里helloA和helloB相等

而如果改变作用域,直接修改scope属性

<?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="hello" class="com.lihuia.singleton.Hello"
scope="prototype"></bean>
</beans>

这种作用域每次实例化bean都会重新创建一个新的bean实例,因此这里返回false

可以换一种输出方式

package com.lihuia.singleton;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* Copyright (C), 2014-2018, lihuia.com
* FileName: Main
* Author: lihui
* Date: 2018/6/24
*/

public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Hello helloA = (Hello)context.getBean("hello");
helloA.setMessage("HelloA");
Hello helloB = (Hello)context.getBean("hello");

System.out.println(helloA.getMessage());
System.out.println(helloB.getMessage());
}
}

这里helloA返回的是HelloA,但是helloB返回的是null;而如果是单例模式,返回的都是HelloA,因为helloA和helloB指向了同一个对象

发表评论