1.单例作用域测试
1.1 创建MainScopeConfig类,添加@Scope注解,括号里不写任何内容,默认就是单例的,在注入@Bean打印给容器中添加person。。。。。我们看看什么时机进行打印
package springanntition.scope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import springorgin.demo.configbean.Person;
@Configuration
public class MainScopeConfig {
/*
@Scope:调整作用域的。
prototype:多实例的,ioc容器启动并不会调用方法创建对象放在容器中,
每次获取的时候才会调用方法创建对象;每一次调用方法就会进入到person()方法new一个,
singleton:单实例的(默认值),ioc容器启动会调用方法创建对象放到ioc容器中,
以后每次获取就直接从容器(map.get())中拿。
request:同一次请求创建一个实例
session:同一个session创建一个实例
* */
@Scope() //相等于bean的scope="prototype"设置成多例的
@Bean("person") // 默认都是单实例的
public Person person() {
System.out.println("给容器中添加person。。。。。");
return new Person("张三", 30);
}
}
1.2 添加测试类来执行
package springanntition.scope;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainScopeTest {
public static void main(String[] args) {
// 测试单例的时候不用获取getBean,在IOC容器被创建的时候创建方法就被调用了
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainScopeConfig.class);
System.out.println("IOC容器创建完成。。。。");
}
}
运行此类:我们发现单例模式是在容器启动时就进入了配置类的person()方法,在容器创建完成之前就完成了注入
我们在来测试下,容器创建完成,我们获取这个person的bean,并多次获取bean,看是否会创建不同的对象
package springanntition.scope;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainScopeTest {
public static void main(String[] args) {
// 测试单例的时候不用获取getBean,在IOC容器被创建的时候创建方法就被调用了
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainScopeConfig.class);
System.out.println("IOC容器创建完成。。。。");
Object bean = context.getBean("person");
Object bean2 = context.getBean("person");
System.out.println(bean == bean2);
}
}
运作一下:我们看从bean里取出两次都是同一个实例就为true,也是因为容器启动前就加载好此bean,所以获取的时候就一直从容器中都是取的同一个。
2.多例作用域测试
@Scope更改为多例的情况咱们再来试试
@Configuration
public class MainScopeConfig {
@Scope("prototype") //相等于bean的scope="prototype"设置成多例的
@Bean("person") // 默认都是单实例的
public Person person() {
System.out.println("给容器中添加person。。。。。");
return new Person("张三", 30);
}
}
测试类这样写,还是先只创建容器并不获取bean
package springanntition.scope;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainScopeTest {
public static void main(String[] args) {
// 测试多例的时候IOC容器创建完成不会创建实例
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainScopeConfig.class);
System.out.println("IOC容器创建完成。。。。");
}
}
运行一下,我们发现IOC容器创建完成之前和之后我们都没有进入过person(),也就是说没有创建实例,那什么时候才创建呢,我们改一下
我们获取一下bean然后运行看下结果
public static void main(String[] args) {
// 测试多例的时候需要获取getBean,因为在容器创建时并不会创建实例
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainScopeConfig.class);
System.out.println("IOC容器创建完成。。。。");
Object bean = context.getBean("person");
}
结果就是在获取bean的时候才会访问person()方法
我们现在来获取多个,看看会出现什么情况,测试代码改成如下
public static void main(String[] args) {
// 测试单例的时候不用获取getBean,在IOC容器被创建的时候创建方法就被调用了
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainScopeConfig.class);
System.out.println("IOC容器创建完成。。。。");
Object bean = context.getBean("person");
Object bean2 = context.getBean("person");
System.out.println(bean == bean2);
}
运行一下:我们发现获取几次bean就会被访问几次person,并且bean实例不等于bean2
prototype:多实例的,ioc容器启动并不会调用方法创建对象放在容器中,每次获取的时候才会调用方法创建对象;每一次调用方法就会进入到person()方法new一个, singleton:单实例的(默认值),ioc容器启动会调用方法创建对象放到ioc容器中,以后每次获取就直接从容器(map.get())中拿。
request:同一次请求创建一个实例
session:同一个session创建一个实例