当在 Spring 中定义一个 bean 时,你必须声明该 bean 的作用域的选项。例如,为了强制 Spring 在每次需要时都产生一个新的 bean 实例,你应该声明 bean 的作用域的属性为 prototype。同理,如果你想让 Spring 在每次需要时都返回同一个bean实例,你应该声明 bean 的作用域的属性为 singleton。Spring 框架支持以下五个作用域,分别为 singleton、prototype、request、session 和 global session。本篇文章只讨论singleton和prototype这两个作用域,一个是单例,一个是多例

一、Bean的作用域是什么?

Bean 的作用域是指 Bean 在 Spring 整个框架中的某种行为模式。比如 singleton 单例作用域,就表示 Bean 在整个 Spring 中只有一份,它是全局共享的,当有人修改了这个值之后,那么另一个人读取到的就是被修改后的值

二、使用步骤

首先我们必须把pom文件坐标导入了才能进行下面的三步

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring_ioc_xml</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>

        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <!-- 数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.31</version>
        </dependency>
    </dependencies>

</project>

1.建立一个实体类User

public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    public User() {
        System.out.println("生命周期:1、创建对象");
    }
    public User(Integer id, String username, String password, Integer age) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.age = age;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        System.out.println("生命周期:2、依赖注入");
        this.id = id;
    }
    public String getUsername() {
        return username;

    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public void initMethod(){
        System.out.println("生命周期:3、初始化");
    }
    public void destroyMethod(){
        System.out.println("生命周期:5、销毁");
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}

代码如下:

2.建立spring的xml文件创建一个User对象的bean

代码如下:可以发现这个是bean对象的scope属性是singleton,表示为单例,也就是你通过这个bean创建再多的对象也其实是同一个对象地址是一样的,通过依赖注入方式给属性赋值后,在进行访问值就改变了

<?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">
    <!--
    scope属性:singleton为单例
    prototype为多例
    -->
    <bean id="studentOne" class="com.atguigu.spring.pojo.Student" scope="singleton">
    <property name="name" value="java助力者"></property>
    <property name="age" value="20"></property>
</bean>
</beans>

3.建立一个测试类

我们这个测试类也很简单就是通过bean创建两个对象,比较他们的内存地址是否一样,如果你的scope属性是singleton那么地址是一样的,因为是单例,如果是prototype为多例,那么地址是不一样的。所以为singleton输出结果为true,为prototype输出结果为false

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanScopeText {
    public static void main(String[] args) {
        ApplicationContext loc=new ClassPathXmlApplicationContext("bean_scope.xml");
        Student student1 = loc.getBean(Student.class);
        Student student2 = loc.getBean(Student.class);
        System.out.println(student1==student2);
        System.out.println(student1.equals(student2));

    }
}

总结

例如:以上就是今天要讲的内容,本文仅仅简单介绍了bean的两个作用域使用,测试了他们的内存地址,其实大家可以测试一下建立单例bean和多例的时候你进行依赖注入的时候,再建一个对象,注入的值到底是怎么样的,显而易见,单例的情况下在建一个对象值也会发送改变,多例则不会