关于spring:Spring中的singleton和prototype

对于spring bean作用域,基于不同的容器,会有所不同,如BeanFactory和ApplicationContext容器就有所不同,在本篇文章,次要解说基于ApplicationContext容器的bean作用域。

对于bean的作用域,在spring中,次要包含singleton,prototype,session,request,global,本篇文章次要解说罕用的两种,即:singleton和prototype.

一  singleton

singleton为单例模式,即scope=”singleton”的bean,在容器中,只实例化一次。

dao示例代码:

package com.demo.dao;

public class UserDao {

    public UserDao(){
        System.out.println("UserDao 无参构造函数被调用");
    }
    //获取用户名
    public String getUserName(){
        //模仿dao层
        return "Alan_beijing";
    }
}

applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="com.demo.dao.UserDao" id="userDao" scope="singleton"/>
</beans>

test:

public class MyTest {

    @Test
    public void test(){
        //定义容器并初始化
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        //定义第一个对象
        UserDao userDao = applicationContext.getBean(UserDao.class);
        System.out.println(userDao.getUserName());

        //定义第二个对象
        UserDao userDao2 = (UserDao) applicationContext.getBean("userDao");
        System.out.println(userDao2.getUserName());
        //比拟两个对象实例是否是同一个对象实例
        System.out.println("第一个实例:"+userDao+"\n"+"第二个实例:"+userDao2);
    }
}

测试后果:

剖析:在测试代码中,将bean定义为singleton,并先后2次通过ApplicationContext的getBean()办法获取bean(userDao),却返回雷同的实例对象:com.demo.dao.UserDao@27a5f880,仔细观察,尽管获取bean两次,然而UserDao的无参构造函数却只被调用一次,这也证实了在容器中,singleton理论只被实例化一次,须要留神的是,Singleton模式的bean,ApplicationContext加载bean时,就实例化了bean。

 定义bean:

测试后果:

如下代码只是加载bean,却没调用getBean办法获取bean,但UserDao却被调用了一次,即实例化。

二 prototype

prototype即原型模式,调用多少次bean,就实例化多少次。

将singleton代码改为原型

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

    <bean class="com.demo.dao.UserDao" id="userDao" scope="prototype"/>
</beans>

测试代码与singleton一样,但后果却不一样:

剖析:通过测试后果,不难发现,调用两次bean,就实例化两次UserDao对象,且对象不一样,须要留神的是,prototype类型的bean,只有在获取bean时,才会实例化对象。

三 singleton和prototype区别

(1)singleton在容器中,只被实例化一次,而prototype在容器中,调用几次,就被实例化几次;

(2)在AppplicationContext容器中,singleton在applicaitonContext.xml加载时就被事后实例化,而prototype必须在调用时才实例化

   singleton:

 定义bean:

测试:

 prototype:

定义bean:

测试:不调用

测试:调用

4.singleton比prototype耗费性能,在web开发中,举荐应用singleton模式,在app开发中,举荐应用prototype模式。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理