Bean的作用域主要有以下5种:
因为globalSession的作用域实践中基本不使用,所以这里就不对其过多介绍了。
另外application的作用域也完全可以用singleton作用域来代替,所以这里也不对其过多介绍了。
所以,我们主要看看singleton、prototype、session、request这四种作用域。
默认情况下,Spring Boot加载的bean都是单例,也就是singleton。
下面我们创建四个类,分别指定singleton、prototype、session、request这四种作用域。
@Component
// spring的Bean默认就是单例,所以这里的注解是可以注释掉的
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class SingletonBean {
}
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrototypeBean {
}
@RequestScope
@Component
public class RequestBean {
}
@SessionScope
@Component
public class SessionBean {
}
我们先来测试一下singleton和prototype作用域,因为这两种适用于所有的spring应用,编写如下启动类:
@Slf4j
public class BeanScopeIocTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(BeanScopeAppConfig.class);
SingletonBean singletonBean1 = context.getBean(SingletonBean.class);
SingletonBean singletonBean2 = context.getBean(SingletonBean.class);
log.warn("singletonBean1 == singletonBean2 => {}",singletonBean1 == singletonBean2);
PrototypeBean prototypeBean1 = context.getBean(PrototypeBean.class);
PrototypeBean prototypeBean2 = context.getBean(PrototypeBean.class);
log.warn("prototypeBean1 == prototypeBean2 => {}", prototypeBean1 == prototypeBean2);
}
}
运行main方法,可以看到如下日志:
和上面对singleton和prototype作用域介绍是一致的。
因为session、request这两个作用域依赖于web应用,所以这里我们写一个简单的controller,代码如下:
@RestController
@RequestMapping("/BeanScopeController")
public class BeanScopeController {
@Autowired
private SessionBean sessionBean;
@Autowired
private RequestBean requestBean;
@GetMapping("/index")
public Map<String, String> index(){
Map<String, String> res = new HashMap<>();
res.put("sessionBean", sessionBean.toString());
res.put("requestBean", requestBean.toString());
return res;
}
}
然后启动应用,浏览器访问该url,查看效果:
重新加载后如下:
可以看到sessionBean的值都是一样的,因为两次访问属于同一个会话,requestBean的值不一样,因为我们发起了两次请求。
接下来,再用谷歌浏览器打开一个无痕窗口(模拟一个新的会话),再次访问该地址,效果如下:
可以看到,此时的sesionBean也和之前的不一样了。
好了,今天就先到这里了,眼过千遍不如手过一遍,赶紧去自己尝试一下吧。。。。拜拜