Bean的六种作用域
其实真实的情况是Spring的IoC容器有两种作用域模式,一种是IoC默认的singleton(单例作用域),一种是可手动修改的prototype(原型作用域 / 多例作用域),在默认情况下,IoC容器采用singleton,也就是所有人获取到的都是同一个Bean对象,这样效率会高很多.每次对该作用域下的Bean的请求都会创建新的实例,获取Bean(指使用ApplicationContext.ge
什么是Bean的作用域呢?
这里的"作用域"还和Java中的类级,方法级等这几个作用域概念不太一样,我自己的一个理解是:在Spring执行的这段时间中,Bean的作用域就只有单例和多例这两种,在执行respect这段时间之中,就有它自己的作用域,而到了session中又有它自己的作用域,像类似的还有application和WebSocket作用域.
我们为什么要了解Bean的作用域呢?
我们在实际应用中,要根据Bean的用法来设置Bean的作用域,比如你和别人一起协同开发的代码中有个Bean不想别人改动,那就可以通过调整Bean的作用域来解决.
下面用一个案例还原案发过程(Spring中的请况):
张三有自己的可爱小猫对象
@Component
public class CatBeans {
@Bean
public Cat cat(){
Cat cat = new Cat();
cat.setName("莫妮卡");
return cat;
}
}
@Component
public class BeanScopes1 {
@Autowired
private Cat cat;
//张三自己调用
public Cat getCat() {
return cat;
}
}
李四看到了,也想要有自己的小猫,所以他用张三的小猫对象复刻了个自己的对象:
@Component
public class BeanScopes2 {
@Autowired
private Cat cat;
//李四调用
public Cat getCat() {
Cat myCat = cat;//李四创建了自己的小猫Bean
myCat.setName("myCat");//李四给自己的猫改了名
return myCat;
}
}
然后他调用了:
发现还挺可爱,简直跟张三的猫一样可爱.
当张三第二次调用自己的小猫的时候,发现自己的猫变了
发现了他的猫不是莫妮卡了,而是被改成myCat,这时候李四也才知道,原来自己的小猫对象和张三的是同一个.
这是为什么呢,李四明明重新建立一个Cat对象啊.
其实真实的情况是Spring的IoC容器有两种作用域模式,一种是IoC默认的singleton(单例作用域),一种是可手动修改的prototype(原型作用域 / 多例作用域),在默认情况下,IoC容器采用singleton,也就是所有人获取到的都是同一个Bean对象,这样效率会高很多.
Spring中怎么修改作用域呢?
这个很简单,只要在想修改作用域的Bean对象那里加个@Scope注解,然后在注解后面加个小括号,小括号里面写上你想改成哪种作用域:(单例)"singleton"或者(多例)"prototype".例如:
@Component
public class CatBeans {
@Scope("prototype")
//@Scope(ConfigurableListableBeanFactory.SCOPE_PROTOTYPE)
//通过Spring内置定义的字符串设置属性也行
@Bean
public Cat cat(){
Cat cat = new Cat();
cat.setName("莫妮卡");
return cat;
}
}
这样就能解决两个人只有一只猫的问题辣.
singleton和prototype这两种都是Spring中的Bean作用域
Spring官方对这两种作用域的描述大致是:
singleton: 在IoC容器中只有一份实例,获取Bean(指使用ApplicationContext.getBean()等方法获取)和装配Bean(即使用@Autowired注入),获取到的都是同一个对象.
场景:Spring中的默认选择
prototype: 每次对该作用域下的Bean的请求都会创建新的实例,获取Bean(指使用ApplicationContext.getBean()等方法获取)和装配Bean(即使用@Autowired注入),获取到的都是新的对象.
场景:通常有状态的Bean使用这个作用域.
还有四种是在Spring MVC中才生效的:
1.request(请求作用域): 一次http请求中会生成一个新的Bean实例类似于prototype
场景: 一次http的请求和响应共享Bean.
2.session(会话作用域): 在http session中定义一个Bean实例
场景: 在用户会话中共享Bean.例如:可以用来记录一个用户的登录信息
3.application(全局作用域): 在⼀个http servlet Context中,定义⼀个Bean实例
场景:Web应用的上下文信息.
4.websocket(HTTP WebSocket作用域): 在一个HTTP WebSocket生命周期中,定义一个Bean实例
场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀
次初始化后,直到WebSocket结束都是同⼀个Bean.
更多推荐
所有评论(0)