Spring注解驱动开发第5和6讲——使用@Scope注解设置组件的作用域及设置懒加载

Spring注解驱动开发第5和6讲——使用@Scope注解设置组件的作用域及设置懒加载,第1张

Spring注解驱动开发第5和6讲——使用@Scope注解设置组件的作用域及设置懒加载 写在前面

  Spring容器中的组件默认是单例的,在Spring启动时就会实例化并初始化这些对象,并将其放到Spring容器中,之后,每次获取对象时,直接从Spring容器中获取,而不再创建对象。如果每次从Spring容器中获取对象时,都要创建一个新的实例对象,那么该如何处理呢?此时就需要使用【@Scope】注解来设置组件的作用域了。

1、@Scope注解概述

@Scope注解能够设置组件的作用域,我们先来看看@Scope注解类的源码,如下所示。


从@Scope注解类的源码中可以看出,在@Scope注解中可以设置如下值:

  1. ConfigurableBeanFactory#SCOPE_PROTOTYPE
  2. ConfigurableBeanFactory#SCOPE_SINGLETON
  3. org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
  4. org.springframework.web.context.WebApplicationContext#SCOPE_SESSION

很显然,在@Scope注解中可以设置的值包括
【ConfigurableBeanFactory】接口中的【SCOPE_PROTOTYPE】和【SCOPE_SINGLETON】;
以及【WebApplicationContext】类中的【SCOPE_REQUEST】和【SCOPE_SESSION】。
是不是很头疼?别急,先来看看【ConfigurableBeanFactory】中写了啥。

1、在ConfigurableBeanFactory接口中有这两个值的常量。

String SCOPE_SINGLETON = “singleton”; --单例模式(默认值):全局有且仅有一个实例

String SCOPE_PROTOTYPE = “prototype”; --多例模式,每次获取Bean的时候都会生成新的实例

2、那【WebApplicationContext】类中这两个值是什么呢?

SCOPE_REQUEST:所对应的值就是 request
SCOPE_SESSION:所对应的值就是 session

【request】 和【session】作用域是需要Web环境来支持的,这两个值基本上使用不到。那这两个值的意义是什么呢?这里记录一下
  request:表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
  session:作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效

2、@Scope注解的使用 2.1单实例bean作用域 写法1(这种写法不理想)

a、新建一个配置类,然后实例化一个Person对象,并将其注入在Spring容器中,如下所示。

输出结果如下:

完整代码
MainConfig2.java

package com.leo.config;

import com.leo.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
@ComponentScan(value = "com.leo")
public class MainConfig2 {

    @Scope//@Scope("singleton"):singleton:表示单例,不写默认就是单例
    @Bean("person")//为这个创建的实例取一个名字
    public Person person() {
        return new Person();
    }
}

test03

    @Test
    public void test03() {
        //AnnotationConfigApplicationContext:该对象是根据读取配置类的方式创建一个ioc容器
        ApplicationContext applicationContext_config = new AnnotationConfigApplicationContext(MainConfig2.class);

        //获取指定的实例对象
        Person bean1 = applicationContext_config.getBean(Person.class);
        System.out.println("bean1的哈希值是:"+bean1.hashCode());

        Person bean2 = applicationContext_config.getBean(Person.class);
        System.out.println("bean2的哈希值是:"+bean2.hashCode());

        if (bean1 == bean2) {
            System.out.println("bean1与bean2是【相等】的,结果为:true");
        } else {
            System.out.println("bean1与bean2是【不相等】的,结果为:false");
        }
    }
写法2

a、配置类中什么都不要写

b、在实体bean上加上@Scope注解

效果是一样的

结论:对象在Spring容器中默认是单实例的,Spring容器在启动时就会将实例对象加载到Spring容器中,之后,每次从Spring容器中获取实例对象,都是直接将对象返回,而不必再创建新的实例对象了。

2.2多实例bean作用域 写法1(这种写法不理想)

@Scope(“prototype”)

运行结果

写法2

直接写在实体bean上

运行结果是i一样的

3、创建单实例bean和多实例bean的区别

  创建单实例bean时:Spring容器在创建的时候,就将@Scope注解标注为singleton的组件进行了实例化,并加载到了Spring容器中。(饿汉模式)
  创建多实例bean时:Spring容器在创建的时候不会立刻将实例注入到spirng容器中,只有在调取的时候才会注入 (懒汉模式)

代码验证单例模式:这里我只是创建了ioc容器,单例这里调用了创建实例的方法。

代码验证多例模式:而多例模式则并没有调用这个创建方法

当调用获取实例的方法后才会调用创建实例的方法。

4、那单例模式下怎么实现懒加载呢?使用注解@Lazy (第6讲)

@Lazy:这注解就是专门为单例模式可以设置懒加载而创建的。只要添加这个注解。那么在单例模式只有调用获取实例时,才会去创建实例。

如下:如果只是生成ioc容器,是不会去调用创建实例bean的方法的

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5695316.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存