一、Bean的单例作用域
众所周知,spring容器中的Bean默认是单例(Singleton)的,任何一个类在容器中只创建一个实例的Bean。下面用代码演示
1、创建应用类
该应用类中只有一个方法,每次调用该方法,就对变量i执行加1的操作。
package com.spring.prototype;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("gernarate")
public class GernerateNumber {
private int i=0;
//生成从1到n的数
public void generate() {
i = i + 1;
System.out.println("我是:" + i);
}
}
2、创建配置类
该配置类中没有实现其它逻辑,只是为了获取容器中的Bean的目的。
package com.spring.prototype;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//配置类
@Configuration
@ComponentScan
public class AnnotationConfig {
}
3、创建测试类
创建测试类,从容器中连续获取5次名字为“gernarate”的Bean,发现每次获取的都是同一个Bean。
package com.spring.prototype;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AnnotationConfig.class);
for(int i=0; i<5; i++){
GernerateNumber gernerator = (GernerateNumber) ctx.getBean("gernarate");
gernerator.generate();
}
}
}
输出结果为:
我是:1
我是:2
我是:3
我是:4
我是:5
从输出结果可以看出,每次获取的Bean都是同一个Bean。
二、Bean的原型作用域
假设一个容器中的Bean注入到一个引用变量中,然后执行了一系列操作,该Bean的实例中变量已经改变。但是另一个引用变量也想引用该Bean未被污染的实例,此时就不能再用默认的单例模式了,而要用原型(Prototype)模式。代码演示
上面的应配置类和测试类均不变,只改变应用类,只是在创建类的时候加上了注解@Scope(“prototype”),如果不加,默认是@Scope(“Singleton”)的。如下:
package com.spring.prototype;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("gernarate")
@Scope("prototype")
public class GernerateNumber {
private int i=0;
//生成从1到n的数
public void generate() {
i = i + 1;
System.out.println("我是:" + i);
}
}
测试输出为:
我是:1
我是:1
我是:1
我是:1
我是:1
从测试结果可以看出,每次获取名字为“gernarate”的Bean时,都生成一个新的实例,摆脱了单例模式。另外容器中还支持会话(Session) 和请求(Rquest),等到web时再继续更新。