还是和上节一样,首先来看下配置类:MainConfig2
@Configuration
名
public class MainConfig2 {
@Scope("singleton") // 默认就是单实例的
@Bean("person")
public Person person(){
System.out.println("给容器中添加Person....");
return new Person("张三", 25);
}
}
再看下person室实体类:
public class Person {
private String name;
private Integer age;
private String nickName;
// 省略...
}
我们知道,在spring中bean默认是单实例的,所以@Scope("singleton")
都一样,我们写个测试类测试一下
@Test
public void test02(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
// System.out.println("ioc容器创建完成....");
// Object bean = applicationContext.getBean("person");
// Object bean2 = applicationContext.getBean("person");
// System.out.println(bean == bean2);
}
打印一下:
给容器中添加Person.... // 容器在一启动的时候便创建好了bean
mainConfig2 // 配置类本身也是bean
person
以上结果可以看出:
容器在一启动的时候便创建好了bean,
我们再将注释放开
@Test
public void test02(){
System.out.println("ioc容器创建完成....");
Object bean = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean == bean2);
}
打印一下:
给容器中添加Person....
ioc容器创建完成....
true
可以得出,结果为true,说明两次获取的bean是一样的,证明了默认是单实例的,
其他保持不变,将@Scope("singleton")
替换成@Scope("prototype")
执行下第一个测试方法:
mainConfig2
person
发现容器并没有创建,说明prototype
作用域下,spring的bean不是随容器启动而创建的
再次执行两个两个测试方法:
@Test
public void test02(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
System.out.println("ioc容器创建完成....");
Object bean = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean == bean2);
}
打印结果:
mainConfig2
person
ioc容器创建完成....
给容器中添加Person....
给容器中添加Person....
false
观察结果说明:获取bean的时候,才动态的创建了bean,并且两个bean不相等,也说明了此时bean是多实例的,自然不相等。
另外其实spring中bean的作用域不止这两种,
spring官方文档描述如下:前两种比较常用,后面的几种几乎用不上
@Scope:调整作用域
prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
每次获取的时候才会调用方法创建对象;
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
以后每次获取就是直接从容器(map.get())中拿,
request:同一次请求创建一个实例
session:同一个session创建一个实例
另外还有需要一提的是,,如果想要单实例,在ioc容器创建的时候不加载,而是在第一次使用bean的时候才加载,可以使用@Lazy注解,加在配置类中创建bean的方法上,加了这个注解后,对于单实例,只会在第一次使用bean的时候加载bean
加油,晚安!