Spring中bean的作用域表示类的作用范围。
有4种表示:
* PROTOTYPE 多例,同时存在多个
* SINGLETON 单例,只存在一个,Spring中默认的作用域
* REQUEST 一次请求内生效(不常用)
* SESSION 一次session内生效(不常用)
可以通过@Scope注解设置
- 设置一个类作为bean
public class Soil {
}
- 设置作用域为单例
@Configuration
public class MainConfig3 {
// singleton单例,默认可以不写这个参数
@Scope(value = SCOPE_SINGLETON)
@Bean
public Soil soil() {
System.out.println("soil initialized");
return new Soil();
}
}
- 编写单例测试类
public class MainTest3 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig3.class);
Object soil_1 = context.getBean("soil");
Object soil_2 = context.getBean("soil");
System.out.println(soil_1 == soil_2);
}
}
输出:
true表示两个是同一个对象
soil initialized
true
- 设置作用域为多例
@Configuration
public class MainConfig3 {
@Scope(value = SCOPE_PROTOTYPE)
@Bean
public Soil soil() {
System.out.println("soil initialized");
return new Soil();
}
}
- 编写多例测试类
public class MainTest3 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig3.class);
Object soil_1 = context.getBean("soil");
Object soil_2 = context.getBean("soil");
System.out.println(soil_1 == soil_2);
}
}
输出:
false表示soil_1和soil_2不是同一个实例对象
soil initialized
soil initialized
false
注意到单例输出只有一个"soil initialized", 而多例输出有2个“soil initialized”,那是因为当类设置为单例时候会在IOC容器启动时候就创建一个对象,避免运行时再创建影响效率;而多例时候只会在每次getBean的时候创建对象。
补充:
对于@Scope设置为singleton也就是单例时候:可以用@Lazy标识这个类标识即使是单例但是也采用懒加载模式,也就是getBean时候再创建这个对象。
@Configuration
public class MainConfig3 {
@Scope(value = SCOPE_SINGLETON)
@Lazy
@Bean
public Soil soil() {
System.out.println("soil initialized");
return new Soil();
}
}
MainTest3类
public class MainTest3 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig3.class);
}
}
输出发现什么都没有
当MainTest3改为:
public class MainTest3 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig3.class);
Object soil_1 = context.getBean("soil");
Object soil_2 = context.getBean("soil");
System.out.println(soil_1 == soil_2);
}
}
输出:
发现只有getBean时候才会输出"soil initialized"并且由于单例所以只输出一次,而且为true
soil initialized
true