spring bean作用域 (一)

Spring 的 Scope大概有五种形式,分别是:

1.Singleton:在Spring Ioc容器中仅存在一个Bean实例,Bean以单实例形式存在。Singleton是Spring的默认配置。

2.Prototype:每次从容器中调用Ben时,都返回一个新的实例。每次调用AnnotationConfigApplicationContext的getBean()方法时,都等价于执行了一次newXxxBean()方法。

3.request:Web项目中,给每一个http request新建一个Bean。

4.session:Web项目中,给每一个http session新建一个Bean。

5.GlobalSession:同一个全局Session共享一个Bean,一般用于Portlet应用环境。

3,4,5仅适应于WebApplicationContext环境中。

今天主要说的是前两种,Singleton和Prototype,即单例模式和多例模式。

Singleton:

Singleton的Bean在同一个Spring Ioc容器中只存在一个实例。

这个例子是在《精通spring 4.x》上看到的,觉得很形象

    <bean id="car" class="com.smart.scope.Car" scope="singleton"></bean>//1
    <bean id="boos1" class="com.smart.scope.Boss" p: car-ref="car"></bean>//2
    <bean id="boss2" class="com.smart.scope.Boss" p: car-ref="car"></bean>//3
    <bean id="boss3" class="com.smart.scope.Boss" p: car-ref="car"></bean>//4
我们在1处把car声明为singleton实例,这个地方也可不写,因为spring的默认状态就是singleton模式,然后我们声明了三个bean,2,3,4。这三个Ben的car属性都是指向同一个Bean(car)的,如图:

在默认情况下,在启动容器AnnotationConfigApplicationContext的时候就会初始化这些singleton的bean,这样做是有很大的好处的。虽然在启动容器的时候要加载大量的bean,浪费一些时间,但是在这个过程中可以发现一些不容易发现的配置问题,还有一点就是这些bean以缓存的形式被保存起来了,当程序运行到需要到他们的地方,不需要再初始化了,提高了运行效率。

刚才提到了,spring在启动的时候便会初始化这些singleton类型的bean,但是并不是每个用户都希望这样,所有spring提供了延迟加载控制:

<bean id="boss2" class="com.smart.scope.Boss" p: car-ref="car" lazy-init="">
但是这个设置不是绝对的,如果这个bean被提前实例化的bean引用了,那么spring就会忽略这个设置。


prototype

同样的例子,

    <bean id="car" class="com.smart.scope.Car" scope="prototype"></bean>//1
    <bean id="boos1" class="com.smart.scope.Boss" p: car-ref="car"></bean>//2
    <bean id="boss2" class="com.smart.scope.Boss" p: car-ref="car"></bean>//3
    <bean id="boss3" class="com.smart.scope.Boss" p: car-ref="car"></bean>//4
在这个配置里面把car定义成prototype,所有每一个boss在调用getBean(Car.class)的时候都会得到一个新的car实例,如图:


spring Ioc容器在启动时不会实例化prototype的Bean,当spring Ioc把prototype的Bean交给调用者以后,就不在关心它的生命周期了。


看一个简单的例子:

1.编写singleton的Bean

@Service
public class DemoSingletonService {
}
2.编写prototype的Bean

@Service
@Scope("prototype")
public class DemoPrototypeService {
}
3.配置类

@Configuration
@ComponentScan("com.example.ch2.scope")
public class ScopeConfig {
}
4.运行主函数类

public class Main {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(ScopeConfig.class);
        DemoSingletonService s1=context.getBean(DemoSingletonService.class);
        DemoSingletonService s2=context.getBean(DemoSingletonService.class);

        DemoPrototypeService d1=context.getBean(DemoPrototypeService.class);
        DemoPrototypeService d2=context.getBean(DemoPrototypeService.class);

        System.out.println("s1==s2 ?  "+s1.equals(s2));
        System.out.println("d1==d2 ?  "+d1.equals(d2));
    }
}
看一下输出结果:





参考《精通spring 4》《springboot 实战》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是饭七分饱

生活在阴沟,也得仰望星空

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值