关于spring:Spring中的singleton和prototype

37次阅读

共计 2404 个字符,预计需要花费 7 分钟才能阅读完成。

对于 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 模式。

正文完
 0