Scope,也称作用域,在Spring Ioc容器指其创建的Bean对象对其他Bean对象的请求可见范围,在Spring IoC 容器中具有以下几种作用域,基本作用域(singleton,prototype),web作用域(request,session,globalsession),自定义作用域。
常见作用域见下表: |作用域|描述| |-|-| |singleton|单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例| |prototype|原型模式,每次通过容器getBean方法获取protetype定义bean,都将产生一个新的bean实例| |request|对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效| |session|对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效| |globalsession|每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效|
实例
在上节的基础上,我们测试@Scope注解的用法。 改写SpringConfiguration配置类,在public Person getPerson()方法上添加@Scope注解。
package com.config;
import com.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
@ComponentScan(basePackages = "com")
public class SpringConfiguration {
@Bean(name = {"p1","person"})
@Scope("singleton") // 等同于@Scope,默认是singleton
public Person getPerson(){
return new Person("zhangsan","男",20);
}
}
改写测试类,从IOC容器中连续两次获取p1对象。测试是否单例。
package com.test;
import com.config.SpringConfiguration;
import com.entity.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
Person person1 = (Person) context.getBean("p1");
Person person2 = (Person) context.getBean("p1");
System.out.println(person1==person2);
}
}
运行结果:
true
将@Scope值改为"prototype"原型模式,测试是否单例。
package com.config;
import com.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
@ComponentScan(basePackages = "com")
public class SpringConfiguration {
@Bean(name = {"p1","person"})
@Scope("prototype" )
public Person getPerson(){
return new Person("zhangsan","男",20);
}
}
运行测试类:
package com.test;
import com.config.SpringConfiguration;
import com.entity.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
Person person1 = (Person) context.getBean("p1");
Person person2 = (Person) context.getBean("p1");
System.out.println(person1==person2);
}
}
运行结果:
false
如果使用XML方式,scope属性使用方式如下:
<bean class="com.entity.Person" name="p1,person" scope="prototype">
<property name="name" value="zhangsan"/>
<property name="gender" value="男"/>
<property name="age" value="20"/>
<property name="car" ref="car"/>
</bean>