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指向了同一个对象