zoukankan      html  css  js  c++  java
  • Spring中单例模式中的饿汉和懒汉以及Spring中的多例模式

    链接:https://pan.baidu.com/s/1wgxnXnGbPdK1YaZvhO7PDQ
    提取码:opjr

    单例模式:每个bean定义只生成一个对象实例,每次getBean请求获得的都是此实例

    单例模式分为饿汉模式和懒汉模式

    饿汉模式:spring singleton的缺省是饿汉模式:启动容器时(即实例化容器时),为所有spring配置文件中定义的bean都生成一个实例

    懒汉模式:在第一个请求时才生成一个实例,以后的请求都调用这个实例

    在网上有许多这样的概念,你也一定烦了吧,我们用代码来看清楚这个过程

    为了展示过程,我们需要引入log4j的jar包,把过程打印在控制台中

    BigKingTest类中的代码如下:

     1 package top.bigking.test;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 import top.bigking.bean.HelloService;
     6 
     7 public class BigKingTest {
     8     public static void main(String[] args) {
     9         System.out.println("开始初始化容器");
    10         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
    11         System.out.println("初始化容器结束");
    12         HelloService helloService = (HelloService) applicationContext.getBean("helloService");
    13         HelloService helloService1 = (HelloService) applicationContext.getBean("helloService");
    14         helloService.sayHello();
    15         helloService1.sayHello();
    16         System.out.println(helloService == helloService1);
    17     }
    18 }

    application.xml的配置如下:

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <beans xmlns="http://www.springframework.org/schema/beans"
    3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5     <bean class="top.bigking.bean.HelloService" id="helloService" scope="singleton" />
    6 </beans>

    控制台的输出如下:

     1  2 开始初始化容器
     3 DEBUG [main] - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3b95a09c
     4 DEBUG [main] - Loaded 1 bean definitions from class path resource [application.xml]
     5 DEBUG [main] - Creating shared instance of singleton bean 'helloService'
     6 初始化容器结束
     7 Hello, World
     8 Hello, World
     9 true
    10 
    11 Process finished with exit code 0

    可以看到,在初始化容器时,helloService的bean对象实例就已经被创建了,后面的两次getBean都无法创建新的实例,而是直接使用这个实例,所以返回了true

    以上,即可证明饿汉模式:启动容器时(即实例化容器时),为所有spring配置文件中定义的bean都生成一个实例,每次getBean请求获得的都是此实例

    接下来我们证明懒汉模式:

    修改application.xml,添加default-lazy-init属性

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <beans default-lazy-init="true" xmlns="http://www.springframework.org/schema/beans"
    3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5     <bean class="top.bigking.bean.HelloService" id="helloService" scope="singleton" />
    6 </beans>

    运行结果如下:

     1  2 开始初始化容器
     3 DEBUG [main] - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3b95a09c
     4 DEBUG [main] - Loaded 1 bean definitions from class path resource [application.xml]
     5 初始化容器结束
     6 DEBUG [main] - Creating shared instance of singleton bean 'helloService'
     7 Hello, World
     8 Hello, World
     9 true
    10 
    11 Process finished with exit code 0

    很明显可以看到,在容器初始化结束后,helloService实例才随着getBean被创建了出来

    这样就证明了懒汉模式:在第一个请求时才生成一个实例,以后的请求都调用这个实例

    问题来了,有了单例模式,那么一定有多例模式

    多例模式:任何一个实例都是新的实例,调用getBean时,就new一个新实例

    应该注意的是:多例模式中,实例只会随着getBean而创建,不会随着容器初始化而创建!也就是说,多例模式只有懒汉!

    默认情况下scope="singleton",那么该Bean是单例

    scope="prototype",则为多例,任何一个实例都是新的实例;

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <beans default-lazy-init="true" xmlns="http://www.springframework.org/schema/beans"
    3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5     <bean class="top.bigking.bean.HelloService" id="helloService" scope="prototype" />
    6 </beans>

    运行看一下结果:

     1  2 开始初始化容器
     3 DEBUG [main] - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3b95a09c
     4 DEBUG [main] - Loaded 1 bean definitions from class path resource [application.xml]
     5 初始化容器结束
     6 Hello, World
     7 Hello, World
     8 false
     9 
    10 Process finished with exit code 0

    可以看到,最后的false

    也就是说,这是两个被实例化的对象,是不同的!

    有人可能会问,为什么控制台中,没有打印出 对象被实例化的相关信息呢?

    这是因为:多例模式的对象,不归IOC容器管理!

    金麟岂是池中物,一遇风云便化龙!
  • 相关阅读:
    CentOS安装部署Nodejs
    CentOS安装部署Git
    CentOS安装部署Mysql 5.7
    CentOS 7 安装Java环境(脚本一键式安装)
    Java技术 | 细谈Java中UUID的简单了解与使用
    Navicat Premium 版本 12.1 激活成永久
    Java技术 | 细谈 Java 8 中的 Base64
    安装部署Elastic Search
    从零开始搭建linux下laravel 5.5所需环境(二)
    从零开始搭建linux下laravel 5.5所需环境(一)
  • 原文地址:https://www.cnblogs.com/ABKing/p/12044025.html
Copyright © 2011-2022 走看看