Bean的作用域

(1)5大作用域
①singleton:在IOC容器中仅存在一个Bean实例,每次返回的都是同一个实例,Bean以单实例的方式存在
②prototype:每次调用getBean()时都会返回一个新的实例
③request:每次HTTP请求都会创建一个新的bean,该作用域仅适用于WebApplicationContext环境
④session:同一个HTTP Session共享一个Bean,不同的HTTP Session 使用不同的Bean。该作用域仅适用于WebApplicationContext环境
⑤global session:和session类似,不过仅在使用portlet context的时候有效。

singleton和prototype是比较原始、比较常用的作用域,目前我们只需要了解这2种作用域。
request、session以及global session这3个作用域,仅仅在基于web的IOC容器(如XmlWebApplicationContext)中有用。如果尝试在普通的 IOC容器(如:XmlBeanFactory或ClassPathXmlApplicationContext)中,使用这些作用域,你将会得到一个IllegalStateException异常(未知的bean作用域)。
这里我们只介绍singleton和prototype,后续再介绍另外3种

(2)通过bean标签的scope属性设置作用域

<bean id="... " class="... " scope="prototype"></bean>

(3)缺省(默认)作用域是singleton

<!-- 没有配置scope属性,默认是singleton -->
<bean id="... " class="... "></bean>

(4)单例bean(作用域为singleton 的bean)
①在创建IOC容器对象时:调用bean的构造器来实例化bean对象;调用set方法为bean的属性赋值。代码验证:

public class HelloWorld {
    private String name;
    public void setName(String name) {
        System.out.println("为属性name赋值");
        this.name = name;
    }
    public HelloWorld(){
        System.out.println("无参构造器");
    }
}
public class Main {
    public static void main(String[] args) {
        //创建IOC容器对象
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}

执行结果:
这里写图片描述
②每次调用getBean(),返回的都是同一个实例。代码示例:

    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("===========================");
        HelloWorld h1=(HelloWorld)context.getBean("hello");
        System.out.println(h1);
        HelloWorld h2=(HelloWorld)context.getBean("hello");
        System.out.println(h2);
        System.out.println(h1==h2);
    }

运行结果:
这里写图片描述
③对于单例bean,只调用一次构造方法(初始化容器对象时),只有一个实例对象,每次调用getBean()返回的都是该实例

(5)原型bean(作用域为prototype的bean)
①在每次调用getBean()时:调用bean的构造器来实例化新的bean对象;调用set方法为bean的属性赋值。

    <!-- 把作用域设置为 prototype-->
    <bean id="hello" class="com.HelloWorld" scope="prototype">
        <property name="name" value="Spring"></property>
    </bean>
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("===========================");
        HelloWorld h1=(HelloWorld)context.getBean("hello");
        System.out.println(h1);
        HelloWorld h2=(HelloWorld)context.getBean("hello");
        System.out.println(h2);
        System.out.println(h1==h2);
    }

运行结果:
这里写图片描述
2)每次调用getBean(),返回的是新的实例

总结:
(1)单例bean(作用域为singleton)
实例化容器对象时,创建bean对象(由IOC容器来创建);
在容器中只维持一个,每次调用getBean()取出的都是同一个;
IOC容器关闭时,销毁单例bean。即销毁取决于Spring容器;
单例bean完全是由IOC容器管理。
(2)原型bean(作用域为prototype)
每次调用getBean()时,创建一个新的bean对象并返回,由IOC容器来创建;
每次取出的都是新的bean对象,并非同一个;
原型bean不是由Spring容器销毁,而是被JVM自动回收(当处于未引用状态时);
IOC创建原型bean后,就不再管他了,因此原型bean并非完全交给Spring容器进行管理的。

对象的创建和销毁,会增加系统的开销。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值