• Bean的作用域和初始化时机(singleton&prototype)


    在Spring中Bean的作用域是可以自己定义的,如果你想每次需要bean时都产生一个新的bean实例时你可以声明Bean的作用域的属性值为prototype。

    而在Spring中Bean的作用域属性默认为singleton,其实也就是单例的。

    Spring 框架支持以下五个作用域,

    作用域描述
    singleton

    在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,默认值

    prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean() 
    request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
    session 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境
    global-session 一般用于Portlet应用环境,该运用域仅适用于WebApplicationContext环境

    本次就只讨论前两个作用域,当你使用web-aware ApplicationContext 的时候,剩余的三个也是可以使用的。

    singleton作用域就是默认的作用域,当你创建Spring IOC的容器是时候,Bean对象无论是否使用,它也会随着Spring Ioc容器一起创建出来。

    当你每次需要获取一个Bean对象的时候,获取的其实都是一个Bean对象。

    创建一个简单的实体类,在无参构造方法里打印一句话

    package com.yjc.beanlife;
    
    public class Student {
        private Integer age;
        private String name;
    
        public Student() {
            System.out.println("初始化时执行无参构造!");
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    在applicationContext.xml把Student声明到Spring 容器当中,设置bean节点的值为singleton(当然也可以不设置,因为默认值就是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 id="student" class="com.yjc.beanlife.Student" scope="singleton"/>
    </beans>

    执行测试方法,在测试方法里加载配置文件,创建Spring容器

    package com.yjc.beanlife;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class BeanTest {
        public static void main(String[] args) {
            ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/yjc/beanlife/applicationContext.xml");
    
        }
    }

    测试结果

     由上图可见,当bean节点的scope属性的值为singleton时,无论你是否使用这个Bean对象,bean初始化的时机是和Spring容器同时创建的。就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。

    接下来把bean节点的scope属性值更改为prototype,修改测试方法

    package com.yjc.beanlife;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class BeanTest {
        public static void main(String[] args) {
            ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/yjc/beanlife/applicationContext.xml");
            Student student = applicationContext.getBean("student", Student.class);
            Student student1 = applicationContext.getBean("student", Student.class);
            System.out.println(student);
            System.out.println(student1);
        }
    }

    测试结果如下

     当bean节点的scope属性值为prototype时,bean的初始化时机就变为了,当你去获取Bean对象的时候,Spring容器才会创建一个对象,而且每一次创建的都是不同的对象。

    根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。

  • 相关阅读:
    js_浏览器对象模型BOM---通过对象来抽象浏览器功能
    js_dom 之事件注册、移除 、pageX
    js组成之dom_dom对象样式操作及运用
    js_组成之DOM_dom对象的注册事件及属性操作
    js_字符串、数组常用方法及应用
    js_内置对象Date Math
    Caffe入门学习(代码实践)
    char和uchar区别
    c/c++中过滤文件路经 后缀
    shell中$(( )) 、 $( ) 、${ }的区别
  • 原文地址:https://www.cnblogs.com/yjc1605961523/p/11752071.html
Copyright © 2020-2023  润新知