在IoC容器最顶级接口BeanFactory 中,有 isSingleton(单例), isPrototype (原型)
两个方法,isSingleton 方法如果返回true ,则bean在IoC容器中以单例存在,这是spring
IoC容器的默认值。
isPrototype 是true 则每次获取bean的时候会创建一个新的bean。
单例(singleton),原型(pototype)即 bean的两种作用域。
spring 共有以下几种作用域
作用域类型 | 使用范围 | 作用域描述 |
---|---|---|
singleton | 所用spring应用 | 默认值,IoC容器只存在单例 |
prototype | 所有spring应用 | 每当从ioc容器中获取一个bean,则创建一个新的bean |
session | spring web 应用 | http 会话 |
application | spring web 应用 | web工程生命周期 |
request | spring web 应用 | web 单次请求 |
globalSession | spring web 应用 | 在一个全局的httpsession 中,一个bean对应一个实例。 |
测试作用域 :
package com.didispace.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 放开则是原型模式,每次返回新实例
public class DataBaseProperties {
@Value("${database.driverName}")
private String driverName;
@Value("${database.url}")
private String url;
@Value("${database.userName}")
private String userName;
@Value("${database.password}")
private String password;
public String getDriverName() {
return driverName;
}
public void setDriverName(String driverName) {
System.out.println(driverName);
this.driverName = driverName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
System.out.println(driverName);
this.url = url;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.didispace.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//@Configuration 代表这时一个java配置文件,
// spring的 容器会根据它来生成IoC容器装配Bean
@Configuration
@ComponentScan(value = "com.didispace.*")
public class AppConfig {
}
package com.didispace;
import com.didispace.bean.DataBaseProperties;
import com.didispace.bean.User;
import com.didispace.config.AppConfig;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class IoCTest {
private static Logger log = Logger.getLogger(IoCTest.class);
public static void main (String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
DataBaseProperties user = ctx.getBean(DataBaseProperties.class);
DataBaseProperties user1 = ctx.getBean(DataBaseProperties.class);
System.out.println(user1 == user);
log.info(user.getUserName());
}
}
代码 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)中
ConfigurableBeanFactory 只有两种类型 SCOPE_SINGLETON, SCOPE_PROTOTYPE
如果想使用 spring web 容器的四种类型,需要使用 WebApplicationContext 去定义其他作用域
如:SCOPE_REQUEST (请求),会话 ( SCOPE_SESSION ) 和应用 ( SCOPE
APPLICATION ) 。