三、Spring的@Scope设置组件作用域

还是和上节一样,首先来看下配置类: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
加油,晚安!

你所看得到的天才不过是在你看不到的时候还在努力罢了!
原文地址:https://www.cnblogs.com/heliusKing/p/11361221.html