zoukankan      html  css  js  c++  java
  • 通俗易懂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+"
    "+"第二个实例:"+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模式。

    四 版权区

     转载博客,必须注明博客出处
     博客园:http://www.cnblogs.com/wangjiming/ (侧重.NET)
     CSDN:https://blog.csdn.net/u010228798  (侧重JAVA)
     如您有新想法,欢迎提出,邮箱:2098469527@qq.com
     专业.NET之家技术QQ群:490539956
     专业化Java之家QQ群:924412846
      有问必答QQ群:2098469527
       一对一技术辅导QQ:2098469527

  • 相关阅读:
    torch上疑问用法总结
    matplotlib库介绍
    java学习总结
    java高级并发编程实战
    java的spi思想--打破双亲委派模型的操作
    linux设置静态ip步骤流程
    jvm调优参数设置
    jvisualvm插件的基本使用
    jvm常见的gc种类
    jvm调优案例与步骤
  • 原文地址:https://www.cnblogs.com/wangjiming/p/11656374.html
Copyright © 2011-2022 走看看