1、简介
@Scope指定bean的作用域。
2、基础类
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
3、@Scope
3.1、取值
@see ConfigurableBeanFactory#SCOPE_PROTOTYPE ==> (prototype)
@see ConfigurableBeanFactory#SCOPE_SINGLETON ==> (singleton)
@see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST ==> (request)
@see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION ==> (session)
3.2、默认值
ConfigurableBeanFactory#SCOPE_SINGLETON ==> (singleton)
3.3、singleton
3.3.1、概述
单实例的,IOC容器启动的时候就会调用方法去创建对象,并将创建的对象放到IOC容器中(一个大的map工厂),以后每次获取该对象就是直接从容器(map.get())中去拿,而不是每次都重新创建一个对象出来,单例模式。
3.3.2、证明单例
3.3.2.1、配置类
@Configuration
public class MainConfig {
/**
* @see ConfigurableBeanFactory#SCOPE_PROTOTYPE
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
*
* prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中,每次获取的时候才会调用方法去创建对象。
* singleton:单实例的(缺省值):ioc容器启动会调用方法去创建对象放到ioc容器中,以后每次获取就是直接从容器(map.get())中拿。
* request:同一次请求创建一个实例
* session:同一个session创建一个实例
*
* @return
*/
@Scope
@Bean("user")
public User user() {
System.out.println("给容器中添加user....");
return new User("张三", 28);
}
}
3.3.2.2、测试类
public class ScopeTest {
@Test
public void test01() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC容器创建完成......");
User user1 = applicationContext.getBean("user", User.class);
User user2 = applicationContext.getBean("user", User.class);
System.out.println(user1 == user2);
}
}
3.3.2.3、测试结果
给容器中添加user....
IOC容器创建完成......
true
PS:
结果分析:
首先我们发现:在创建容器的时候(创建完之前)就开始实例化各种scope为singleton的bean到容器中。然后才是容器创建完,当获取多次这个bean的时候,都不会重新创建对象,而是直接从容器中获取的,所以获取了两次都返回了同一个对象,所以对比地址返回true。
3.3.3、证明在创建容器的时候就实例化单例bean
3.3.3.1、修改测试类
public class ScopeTest {
@Test
public void test01() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC容器创建完成......");
}
}
3.3.3.2、测试结果
给容器中添加user....
IOC容器创建完成......
3.4、prototype
3.4.1、概述
多实例的:IOC容器启动并不会去调用方法创建对象并放到容器中,每次只有当你获取该对象的时候才会去调用方法创建该对象,并且不是单例的,每次获取都会创建一个新的对象。
3.4.2、证明多例
3.4.2.1、配置类
@Scope("prototype")
@Bean("user")
public User user() {
System.out.println("给容器中添加user....");
return new User("张三", 28);
}
3.4.2.2、测试类
public class ScopeTest {
@Test
public void test01() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC容器创建完成......");
User user1 = applicationContext.getBean("user", User.class);
User user2 = applicationContext.getBean("user", User.class);
System.out.println(user1 == user2);
}
}
3.4.2.3、测试结果
IOC容器创建完成......
给容器中添加user....
给容器中添加user....
false
PS:
结果分析:
可以发现:IOC容器先是创建完成了(这时候并没有创建bean),然后我们getBean(),这个时候开始往容器中真正的添加bean,并且是每一次获取对象,都会重新创建出一个新的实例来,所以两个对象对比是false。
3.5、其他
request、session不讲解。
4、广告
-
码云点star,万分感谢!
代码已经上传到码云了
https://gitee.com/geekerdream/spring-anonation
通用的权限处理框架
https://gitee.com/geekerdream/common-security
通用的异常处理
https://gitee.com/geekerdream/exception-handler
通用的发送邮件
https://gitee.com/geekerdream/common-boot-email
陆续会推出更多干货,希望关注!
-
QQ群【Java初学者学习交流群】:458430385
-
微信公众号【Java码农社区】
![](https://img.haomeiwen.com/i4582242/ca4a357ae859b1aa.jpg)
- 今日头条号:编程界的小学生
网友评论