Spring框架笔记(七)——Spring IOC容器Bean的作用域

Easter79
• 阅读 761

每个Bean都有自己的作用域,它们会在特定的时间生成,在特定的范围生存。Spring IOC容器的bean有四种作用域:

Spring框架笔记(七)——Spring IOC容器Bean的作用域

其中默认的作用域是singleton,单例模式。也就是我们之前配置的bean的作用域模式,即所有的bean只有一个,并且在一开始就生成了。

prototype则是在每次getBean的时候都会生成一个新的实例。

request则是以每次请求作用作用域,session则是Http Session被创建的时候被创建的,并且作用域适用于WebApplicationContext环境。

好,我们今天主要看看前两者:

我们先将CarBean定义给出,这里我们在构造方法里加入了控制台输出信息。

package com.happyBKs.autowire;

public class CarBean {
    String brand;
    double price;
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public CarBean(String brand, double price) {
        super();
        this.brand = brand;
        this.price = price;
    }
    public CarBean() {
        super();
        System.out.println(this.brand+" Constructor ....");
    }
    @Override
    public String toString() {
        return "CarBean [brand=" + brand + ", price=" + price + "]";
    }
    
}

IOC容器配置:\src\main\resources\bean-scopes.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="carBM" class="com.happyBKs.autowire.CarBean" p:brand="BM"
        p:price="400000" scope="singleton" />
    <bean id="carAudi" class="com.happyBKs.autowire.CarBean" p:brand="Audi"
        p:price="300000" scope="prototype" />

</beans>

测试代码:

@Test
    public void testScope1() {
        
        {
            System.out.println("example 1:");
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean-scopes.xml");
            System.out.println("getBean(carBM)");
            CarBean cb = (CarBean) ac.getBean("carBM");
            System.out.println(cb);
        }
    
        {
            System.out.println("example 2:");
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean-scopes.xml");
            System.out.println("getBean(carAudi)");
            CarBean cb = (CarBean) ac.getBean("carAudi");
            System.out.println(cb);
        }
    }

输出结果:

example 1:

七月 18, 2015 10:32:13 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@191d7bd5: startup date [Sat Jul 18 22:32:13 CST 2015]; root of context hierarchy

七月 18, 2015 10:32:13 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [bean-scopes.xml]

null Constructor ....

getBean(carBM)

CarBean [brand=BM, price=400000.0]

example 2:

七月 18, 2015 10:32:14 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3e9c00ea: startup date [Sat Jul 18 22:32:14 CST 2015]; root of context hierarchy

七月 18, 2015 10:32:14 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [bean-scopes.xml]

null Constructor ....

getBean(carAudi)

null Constructor ....

CarBean [brand=Audi, price=300000.0]

注意了,第二个例子中有两个null Constructor ....

第一个是carBM在加载IOC容器配置文件时自动加载的,因为那个bean是singleton的作用域,即使不使用它,也会被构造。

第二个是在getBean时加载的,只有需要时才会被构造。

那么你也许会问?真的是重新被构造了吗?我再给例子吧。

我们分别用同一个容器,getBean两次,看看singleton和protoType作用域下返回对象的区别:

singleton

@Test
    public void testScope2() {
        
        
        
        ApplicationContext ac1 = new ClassPathXmlApplicationContext(
                "bean-scopes.xml");
        CarBean cb1 = (CarBean) ac1.getBean("carBM");
        System.out.println(cb1);
        
        CarBean cb2 = (CarBean) ac1.getBean("carBM");
        System.out.println(cb2);
        
        if(cb1==cb2)
        {
            System.out.println("the same one!");
        }
        else
        {
            System.out.println("different!");
        }
        

    }

输出:

七月 18, 2015 10:45:24 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@75e81ab3: startup date [Sat Jul 18 22:45:24 CST 2015]; root of context hierarchy

七月 18, 2015 10:45:24 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [bean-scopes.xml]

null Constructor ....

CarBean [brand=BM, price=400000.0]

CarBean [brand=BM, price=400000.0]

the same one!

protoType

@Test
    public void testScope3() {
        
        
        
        ApplicationContext ac1 = new ClassPathXmlApplicationContext(
                "bean-scopes.xml");
        CarBean cb1 = (CarBean) ac1.getBean("carAudi");
        System.out.println(cb1);
        

        CarBean cb2 = (CarBean) ac1.getBean("carAudi");
        System.out.println(cb2);
        
        if(cb1==cb2)
        {
            System.out.println("the same one!");
        }
        else
        {
            System.out.println("different!");
        }
        

    }

输出结果:

七月 18, 2015 10:46:12 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@72f9ebcd: startup date [Sat Jul 18 22:46:12 CST 2015]; root of context hierarchy

七月 18, 2015 10:46:12 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [bean-scopes.xml]

null Constructor ....

null Constructor ....

CarBean [brand=Audi, price=300000.0]

null Constructor ....

CarBean [brand=Audi, price=300000.0]

different!

但是,请注意,如果是不同的ApplicationContext,也就是两个不同的容器,那么无论什么作用域类型,返回的对象一定不是同一个。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Spring中管理Bean依赖注入之后和Bean销毁之前的行为
    对于Singleton作用域的Bean,Spring容器将会跟踪它们的生命周期,容器知道何时实例化结束、何时销毁。Spring可以管理Bean在实例化结束之后和Bean销毁之前的行为。Bean依赖关系注入之后的行为:    Spring提供了两种方式在Bean全部属性设置成功后执行特定的行为:在Spring配置文件
Wesley13 Wesley13
3年前
JAVA记录
singleton作用域:当把一个Bean定义设置为singleton作用域是,SpringIoC容器中只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean定义相匹配,则只会返回该Bean的同一实例。值得强调的是singleton作用域是Spring中的缺省作用域。prototype作用域:protot
Easter79 Easter79
3年前
Spring容器中Bean的作用域
当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域:singleton:单例模式,在整个SpringIoC容器中,使用singleton定义的Bean将只有一个实例prototype:原型模式,每次通过容器
Easter79 Easter79
3年前
Spring中的bean是线程安全的吗?
结论:不是线程安全的Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策略,因此可以说Spring容器中的Bean本身不具备线程安全的特性,但是具体还是要结合具体scope的Bean去研究。Spring的bean作用域(scope)类型:singleton:单例,默认作用域。p
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k