IOC的单例和多例

Posted tsvv-plus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOC的单例和多例相关的知识,希望对你有一定的参考价值。

  Spring容器在默认情况下管理的bean是单例(singleton)的,即该bean只会创造一个对象,无论之后调用多少次该bean,都只会返回同一个对象。

  多例(prototype)模式,每次调用同一个bean,都会创造不同的对象。

 

实验:

  两个实验类:

package com.tsvv.pojo;

public class Apple {

}

---------------------------------------

package com.tsvv.pojo;

public class Orange {

}

  application.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-3.2.xsd">

    <!-- scope属性控制当前bean的创建模式: 
        singleton:单例模式中,默认为是此模式
        prototype:多例模式 -->

    <bean id="apple" class="com.tsvv.pojo.Apple" scope="singleton"></bean>
    <bean id="orange" class="com.tsvv.pojo.Orange" scope="prototype"></bean>
    
</beans>

  Test:

package com.tsvv.ioc;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tsvv.pojo.Apple;
import com.tsvv.pojo.Orange;

public class TestDemo {
    
    ApplicationContext context = 
            new ClassPathXmlApplicationContext("application.xml");
    
    @Test
    public void testScope() {
        Apple apple1=(Apple)context.getBean("apple");
        Apple apple2=(Apple)context.getBean("apple");
        Apple apple3=(Apple)context.getBean("apple");
        Orange orange1=(Orange)context.getBean("orange");
        Orange orange2=(Orange)context.getBean("orange");
        Orange orange3=(Orange)context.getBean("orange");
        System.out.println("apple1----->"+apple1);
        System.out.println("apple2----->"+apple2);
        System.out.println("apple3----->"+apple3);
        System.out.println("orange1----->"+orange1);
        System.out.println("orange2----->"+orange2);
        System.out.println("orange3----->"+orange3);
    }

}

  结果:

apple1----->com.tsvv.pojo.Apple@4386f16
apple2----->com.tsvv.pojo.Apple@4386f16
apple3----->com.tsvv.pojo.Apple@4386f16
orange1----->com.tsvv.pojo.Orange@363ee3a2
orange2----->com.tsvv.pojo.Orange@4690b489
orange3----->com.tsvv.pojo.Orange@79b06cab

 

区别与联系:

  单例模式和多例模式属于对象模式,但是单例模式的对象在整个系统中只有一份,多例模式可以有多个实例;它们都不对外提供构造方法,即构造方法都为私有

  之所以用单例,是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存

  之所以用多例,是为了防止并发问题:即一个请求改变了对象的状态,此时对象又处理另一个请求,而之前请求对对象状态的改变导致了对象对另一个请求做了错误的处理;

  用单例和多例的标准只有一个:当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例;

 

生命周期:

  单例:

    bean在单例模式下,IOC容器启动时解析xml发现该bean标签后,直接创建该bean的对象存入内部map中保存,此后无论调用多少次getBean()获取该bean都是从map中获取该对象返回,一直是一个对象。此对象一直被IOC容器持有,直到容器退出时,随着容器的退出对象被销毁。

  多例:

    bean在多例模式下,IOC容器启动时解析xml发现该bean标签后,只是将该bean进行管理,并不会创建对象,此后每次使用 getBean()获取该bean时,IOC都会重新创建该对象返回,每次都是一个新的对象。这个对象IOC容器并不会持有,何时销毁取决于使用该对象的用户自己什么时候销毁该对象。

 

以上是关于IOC的单例和多例的主要内容,如果未能解决你的问题,请参考以下文章

spring 对象的单实例和多实例

spring单例和非单例的问题

单例和多例的区别

单例和多例的区别

单例和多例的区别

java单例和多例