Bean的作用域

默认情况下,注入到IOC容器中的bean都是单例的,当从容器中多次获取bean时,获取到的都是同一个bean的对象。因为,在bean注入到IOC容器中时,scope属性默认为singleton的,即单例的,同时,scope还可以指定prototype、request、session类型的。

【一】XML的配置形式

1、singleton类型的

<!--scope="singleton"属性指定注入的bean为单例的-->
<bean id="car" class="com.lzj.spring.Car" scope="singleton">
        <property name="brand" value="baoma"></property>
        <property name="price" value="100000"></property>
    </bean>

当从容器中获取bean时,

ClassPathXmlApplicationContext ctx = 
                new ClassPathXmlApplicationContext("bean.xml");
        Car car = (Car) ctx.getBean("car");
        Car car2 = (Car) ctx.getBean("car");

获取到的car对象和car2对象是同一个对象。该对象在容器初始化时就自动创建了(执行了Car的构造函数)。

2、prototype类型的

<!--scope="prototype"属性指定注入的bean为原型的-->
<bean id="car" class="com.lzj.spring.Car" scope="prototype">
        <property name="brand" value="baoma"></property>
        <property name="price" value="100000"></property>
    </bean>

当从容器中获取bean时,

ClassPathXmlApplicationContext ctx = 
                new ClassPathXmlApplicationContext("bean.xml");
        Car car = (Car) ctx.getBean("car");
        Car car2 = (Car) ctx.getBean("car");

获取到car对象和car2对象不是一个对象,是同一个java bean的两个实现对象。

未完。。。

【二】、注解的形式配置

一、Bean的单例作用域

众所周知,spring容器中的Bean默认是单例(Singleton)的,任何一个类在容器中只创建一个实例的Bean。下面用代码演示

1、创建应用类

该应用类中只有一个方法,每次调用该方法,就对变量i执行加1的操作。

package com.spring.prototype;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("gernarate")
public class GernerateNumber {
    private int i=0;

    //生成从1到n的数
    public void generate() {
        i = i + 1;
        System.out.println("我是:" + i);
    }
}

2、创建配置类
该配置类中没有实现其它逻辑,只是为了获取容器中的Bean的目的。

package com.spring.prototype;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

//配置类
@Configuration
@ComponentScan
public class AnnotationConfig {

}

3、创建测试类
创建测试类,从容器中连续获取5次名字为“gernarate”的Bean,发现每次获取的都是同一个Bean。

package com.spring.prototype;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestMain {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AnnotationConfig.class);
        for(int i=0; i<5; i++){
            GernerateNumber gernerator = (GernerateNumber) ctx.getBean("gernarate");
            gernerator.generate();
        }
    }
}

输出结果为:

我是:1
我是:2
我是:3
我是:4
我是:5

从输出结果可以看出,每次获取的Bean都是同一个Bean。

二、Bean的原型作用域

假设一个容器中的Bean注入到一个引用变量中,然后执行了一系列操作,该Bean的实例中变量已经改变。但是另一个引用变量也想引用该Bean未被污染的实例,此时就不能再用默认的单例模式了,而要用原型(Prototype)模式。代码演示
上面的应配置类和测试类均不变,只改变应用类,只是在创建类的时候加上了注解@Scope(“prototype”),如果不加,默认是@Scope(“Singleton”)的。如下:

package com.spring.prototype;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("gernarate")
@Scope("prototype")
public class GernerateNumber {
    private int i=0;

    //生成从1到n的数
    public void generate() {
        i = i + 1;
        System.out.println("我是:" + i);
    }
}

测试输出为:

我是:1
我是:1
我是:1
我是:1
我是:1

从测试结果可以看出,每次获取名字为“gernarate”的Bean时,都生成一个新的实例,摆脱了单例模式。另外容器中还支持会话(Session) 和请求(Rquest),等到web时再继续更新。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值