• [译]8-spring bean的作用域


    在spring中使用<bean/>标签定义bean的时候,可以使用scope属性来定义bean的作用域.如果想要每次

    从spring容器得到一个新创建的bean实例,可以指定scope="prototype";如果想要每次从spring容器得

    到同一个bean实例,可以指定scope="singleton"

    spring中bean的作用域有如下5种类,其中有3中适用于web应用程序.5中作用域的介绍如下:

    作用域 说明
    singleton 单例bean.整个IOC容器中只有该bean的一个实例
    prototype 原型.每次从spring IOC容器中得到的都是新创建的bean
    request 每次http请求都会创建一个bean.只适用于web应用
    session 每个session共用一个bean.只适用于web应用
    global-session 整个web应用中只会实例化一次该bean

    本文我们只介绍singleton和prototype作用域.

     

    singleton作用域

    在spring IOC容器中的bean如果scope指定为singleton,那么该bean在此IOC容器中只会存在一个实例.

    首次从spring IOC容器中获得该bean的时候,spring IOC容器会实例化并装配该bean,随后把该bean

    缓存起来,以后在从spring IOC容器取得该bean的时候,IOC容器会把缓存的bean实例返回.

    下面看一个singleton作用域的例子程序.

    1.创建com.tutorialspoint.scope.singleton包,并在包中创建HelloWorld.java类,内容如下:

    package com.tutorialspoint.scope.singleton;
    
    public class HelloWorld {
        
        private String message;
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public void getMessage() {
            System.out.println("Your Message : " + message);
        }
    }

     2.在src目录下,创建scope_singleton.xml配置文件,内容如下:

        在配置文件中,指定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-3.0.xsd">
    
       <bean id="helloWorld" class="com.tutorialspoint.scope.singleton.HelloWorld" scope="singleton"/>
    
    </beans>

    3.在包com.tutorialspoint.scope.singleton中创建MainApp.java,内容如下:

    package com.tutorialspoint.scope.singleton;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainApp {
    
        public static void main(String[] args) {
            
            //实例化spring IOC容器
            ApplicationContext context = new ClassPathXmlApplicationContext("scope_singleton.xml");
            //从容器中得到作用域为singleton的helloWorld bean.并强制转换为HelloWorld
            HelloWorld objA = (HelloWorld)context.getBean("helloWorld");
            //调用objA的setMessage方法,给成员变量message赋值
            objA.setMessage("I am object A");
            //打印objA的成员变量message
            objA.getMessage();
            //再次从spring IOC容器中得到作用域为single的的helloWorld bean
            HelloWorld objB = (HelloWorld)context.getBean("helloWorld");
            //直接得到objB的成员变量message,可以发现objB的message也被赋值了,说明从IOC容器中得到的是同一个bean实例
            objB.getMessage();
            //再次确认,看看objA和objB所引用的对象是否是同一个对象,从打印信息中可以验证objA和objB确实是同一个对象
            System.out.println(objA==objB);
        }
    }

    4.运行程序验证结果,如下:

    最后我们修改scope_singleton.xml配置文件,把scope="singleton"去掉,再次运行程序.发现两次运行

    结果完全一致.这就证明了:spring IOC容器所管理的bean的作用域默认情况下是singleton

    prototype作用域

    spring IOC容器所管理的scope为prototype的bean,在每次用户请求从IOC容器中得到该bean的时候,都

    会新创建该bean的一个实例,并返回给用户.一般情况有状态的bean的scope会被设置为prototype;无状态

    bean的scope设置为singleton.(可以简单的认为有成员变量,并且会对该变量进行修改的类都是有状态的).

    下面做实验,实验代码跟singleton例子中的代码完全一致,只是配置元数据不同.还是在敲一遍吧

    1.新建包com.tutorialspoint.scope.prototype,并在包中新建HelloWorld.java,内容如下:

    package com.tutorialspoint.scope.prototype;
    
    public class HelloWorld {
        
        private String message;
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public void getMessage() {
            System.out.println("Your Message : " + message);
        }
    }

     2.在src目录下新建scope_prototype.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.0.xsd">
       
       <!-- 指定helloWorld bean的scope作用域为prototype -->
       <bean id="helloWorld" class="com.tutorialspoint.scope.prototype.HelloWorld" scope="prototype"/>
    
    </beans>

    3.在包com.tutorialspoint.scope.prototype中新建类MainApp.java,内容如下:

    package com.tutorialspoint.scope.prototype;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainApp {
       public static void main(String[] args) {
          //实例化spring IOC容器
          ApplicationContext context = new ClassPathXmlApplicationContext("scope_prototype.xml");
          //从容器中得到作用域为prototype的helloWorld bean.并强制转换为HelloWorld
          HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
          //设置objA的message成员变量
          objA.setMessage("I'm object A");
          //得到objA的message成员变量
          objA.getMessage();
          //再次从spring IOC容器中得到作用域为prototype的helloWorld bean
          HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
          //获取objB的message的成员变量.发现message为null,证明objA和objB不是同一个实例
          objB.getMessage();
          //进一步验证objA和objB所引用的对象是否是同一个
          System.out.println(objA==objB);
       }
    }

    4.运行程序,验证结果,发现IOC容器中scope为prototype的bean会为每个请求重新创建实例.

     

  • 相关阅读:
    数据库高级链表查询,重点可以多看看
    数据库多表查询,一对一关系,一对多关系,多对多关系
    Django基础
    前端之JavaScript
    前端之Jquery
    CF888E Maximum Subsequence-折半搜索
    HNOI2010 平面图判定
    CEOI 2011Traffic
    LuoguP1710 地铁涨价
    Luogu2059 卡牌游戏-概率DP
  • 原文地址:https://www.cnblogs.com/sysman/p/4478745.html
Copyright © 2020-2023  润新知