当前位置: 首页 > 图灵资讯 > 技术篇> Bean的作用域

Bean的作用域

来源:图灵教育
时间:2023-06-04 09:13:37

1.SpringIoC容器创建的Bean对象在Singleton371.1默认情况下是单例的

测试一下:

package com.powernode.spring6.bean;////Bean的作用域  37public class SpringBean {}

Bean的作用域  37-->    <bean id="sb" class="com.powernode.spring6.bean.SpringBean">    bean>

@Test    public void testBeanScope(){        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-scope.xml");        SpringBean sb = applicationContext.getBean("sb", SpringBean.class);        System.out.println(sb);        ///我们想知道这个SpringBean是单例还是多例。        SpringBean sb2 = applicationContext.getBean("sb", SpringBean.class);        System.out.println(sb2);        SpringBean sb3 = applicationContext.getBean("sb", SpringBean.class);        System.out.println(sb3);    }

Bean的作用域_spring

在Spring的IOC容器中,Bean对象在默认情况下是单例的。

可以看出,这一次在Spring上下文初始化时,并没有创建Bean对象。

那你可能会问:如果scope没有配置,它的默认值是什么?默认值为singleton,单例。

1.2这个对象是什么时候创建的?37

可为SpringBean提供一种无参数结构方法进行测试,如下:

package com.powernode.spring6.bean;////Bean的作用域  37public class SpringBean {    public SpringBean() {        System.out.println(实施了SpringBean的无参结构方法”);    }}

@Test    public void testBeanScope(){    /**         * 1. 默认情况下Spring是如何管理这个Bean的:         *      Bean在默认情况下是单例。(单例:singleton)         *      当Spring上下文初始化时,实例化。         *      每次调用getbean()方法时,都会返回单例对象。         *         */        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-scope.xml");    }

Bean的作用域_System_02

根据测试,在默认情况下,Bean对象的创建是在初始化Spring的上下文中完成的

2.protype37

要使Spring的Bean对象以多种形式存在,可在Bean标签中指定Scope属性的值为:prototype,这样,每次执行getbean()方法时,Spring就会创建bean对象,调用几次就会创建几次。

需要在bean的配置文件中添加属性scope=”prototype"

 <bean id="sb" class="com.powernode.spring6.beans.SpringBean" scope="prototype" />

@Test    public void testBeanScope(){        /**         * 1. 默认情况下Spring是如何管理这个Bean的:         *      Bean在默认情况下是单例。(单例:singleton)         *      当Spring上下文初始化时,实例化。         *      每次调用getbean()方法时,都会返回单例对象。         *         * 2. 将bean的scope属性设置为prototype:         *      bean是多例的。         *      当spring上下文初始化时,这些prototype的bean就不会初始化。         *      每次调用getbean()方法时,实例化bean对象。         *      prototype翻译为:原型。         */        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-scope.xml");        SpringBean sb = applicationContext.getBean("sb", SpringBean.class);        System.out.println(sb);        ///我们想知道这个SpringBean是单例还是多例。        SpringBean sb2 = applicationContext.getBean("sb", SpringBean.class);        System.out.println(sb2);        SpringBean sb3 = applicationContext.getBean("sb", SpringBean.class);        System.out.println(sb3);    }

Bean的作用域_spring_03'

3.scope的其他选项,Bean作用域3.1scope属性值不止两个,共8个选项:38

●singleton:默认,单例。

●prototype:原型。每次调用getbean()方法,就可以获得新的bean对象。或者每次注入都是新对象。

●request:一个请求对应一个Bean。仅限于WEB应用。

●session:一个会话对应一个Bean。仅限于WEB应用。

●globalsession:portlet应用中专用。如果在servlet的WEB应用中使用globalsesion,则与session相同。(portlet和servlet都是标准的。servlet在servlet容器中运行,如tomcat。portlet在portlet容器中运行。)

●application:一个应用对应一个Bean。仅限于WEB应用。

●websocket:一个websocket生命周期对应一个bean。仅限于WEB应用。

●自定义scope:很少使用。

3.2scope自定义scope:很少使用39

接下来,让我们定制一个Scope。线程级Scope在同一线程中获得相同的Bean。跨线程是不同的对象:(以下内容作为理解)

●第一步:自定义Scope。(实现Scope接口)

○Spring内置线程范围类:org.springframework.context.support.SimpleThreadScope,可直接使用。

●第二步:在Spring容器中注册自定义Scope。

<!--    配置我们自定义的作用域  39-->    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">        <property name="scopes">            <map>                <entry key="threadScope">                    <!--Spring框架内置用于Scope接口的实现类。--Spring框架内置用于Scope接口的实现类。也可以自定义。-->                    <bean class="org.springframework.context.support.SimpleThreadScope"/>                </entry>            </map>        </property>    </bean>

第三步:使用Scope。

编写测试程序:

///测试SpringBean是否安全   39    @Test    public void testThreadScope(){        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-scope.xml");        SpringBean sb = applicationContext.getBean("sb", SpringBean.class);        System.out.println(sb);        SpringBean sb1 = applicationContext.getBean("sb", SpringBean.class);        System.out.println(sb1);        // 启动新的线程        new Thread(new Runnable() {            @Override            public void run() {                SpringBean sb2 = applicationContext.getBean("sb", SpringBean.class);                System.out.println(sb2);                SpringBean sb3 = applicationContext.getBean("sb", SpringBean.class);                System.out.println(sb3);            }        }).start();    }

Bean的作用域_spring_04