spring IoC-bean标签的scope属性、bean的作用范围和生命周期

提出问题

<bean id="UserSrvImpl" class="top.malaoshi.UserSrvImpl">
</bean>

在上面的配置中 什么时候创建的 top.malaoshi.UserSrvImpl 类对象,是单例 还是 多例模式,什么时候销毁的该对象?

这是本文要解决的问题

概述

本文介绍 spring <bean scope=""> 的 scope 属性

scope 属性非常重要,决定着 bean 对象的作用范围和生命周期

有以下几个值:

  • singleton:单例模式,默认值(最常用)
  • prototype:多例。每次都创建一个新对象(较常用)
  • request:用于web项目,当有新的Http请求时,就会创建一个新对象,在该请求期间,是单例的
  • session:用于web项目,当有新的Http session时,就会创建一个新对象,在当前session期间,是单例的
  • global-session:用于web项目,应用在集群,全局session。
    不是集群时,功能同session。

singleton

单例模式,默认值(最常用)

生命周期:

  • 创建:spring容器创建时,就开始创建该对象
  • 生存:只要容器在,对象一直活着
  • 死亡:容器销毁时,对象就销毁了

体验

spring.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="UserSrvImpl" class="top.malaoshi.UserSrvImpl">
    </bean>
</beans>

没有 scope 属性,即:默认为 单例模式

UserSrvImpl如下:
public class UserSrvImpl implements IUserService {

    public UserSrvImpl(){
        System.out.println("UserSrvImpl构造方法");
    }
    public void save(String username,String password){
        System.out.println("保存 "+username+","+password+" 成功!");
    }
}

增加默认构造方法,并且打印一段文字

主启动类:
public class Main {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");

        IUserService srv=(IUserService)ac.getBean("UserSrvImpl");
        IUserService srv2=(IUserService)ac.getBean("UserSrvImpl");
        System.out.println(srv==srv2);
    }
}

执行结果:

UserSrvImpl构造方法
true

在主启动类中调用了 2 次 ac.getBean("UserSrvImpl") ,但只打印了一次 UserSrvImpl构造方法,说明只调用了一次 UserSrvImpl 构造方法,所以 srv==srv2 为 true

prototype

多例。每次都创建一个新对象(较常用)

生命周期:

  • 创建:当使用对象时,创建新的对象实例。
  • 生存:只要对象在使用中,就一直活着。
  • 死亡:由 java 垃圾回收器回收

体验

spring.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="UserSrvImpl" class="top.malaoshi.UserSrvImpl" scope="prototype">
    </bean>
</beans>

增加 scope="prototype" ,即:多例模式

UserSrvImpl如下:
public class UserSrvImpl implements IUserService {

    public UserSrvImpl(){
        System.out.println("UserSrvImpl构造方法");
    }
    public void save(String username,String password){
        System.out.println("保存 "+username+","+password+" 成功!");
    }
}

增加默认构造方法,并且打印一段文字

主启动类:
public class Main {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");

        IUserService srv=(IUserService)ac.getBean("UserSrvImpl");
        IUserService srv2=(IUserService)ac.getBean("UserSrvImpl");
        System.out.println(srv==srv2);
    }
}

执行结果:

UserSrvImpl构造方法
UserSrvImpl构造方法
false

在主启动类中调用了 2 次 ac.getBean("UserSrvImpl") ,打印了 两次 UserSrvImpl构造方法 ,说明调用了两次 UserSrvImpl 构造方法,创建了2个对象,所以 srv==srv2 为 false


原文出处:/show_1IX1mKQApo4.html