Spring容器中的组件默认是单例的,在Spring启动时就会实例化并初始化这些对象,并将其放到Spring容器中,之后,每次获取对象时,直接从Spring容器中获取,而不再创建对象。如果每次从Spring容器中获取对象时,都要创建一个新的实例对象,那么该如何处理呢?此时就需要使用【@Scope】注解来设置组件的作用域了。
1、@Scope注解概述@Scope注解能够设置组件的作用域,我们先来看看@Scope注解类的源码,如下所示。
从@Scope注解类的源码中可以看出,在@Scope注解中可以设置如下值:
- ConfigurableBeanFactory#SCOPE_PROTOTYPE
- ConfigurableBeanFactory#SCOPE_SINGLETON
- org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
- 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内有效
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容器中获取实例对象,都是直接将对象返回,而不必再创建新的实例对象了。
@Scope(“prototype”)
运行结果
直接写在实体bean上
运行结果是i一样的
创建单实例bean时:Spring容器在创建的时候,就将@Scope注解标注为singleton的组件进行了实例化,并加载到了Spring容器中。(饿汉模式)
创建多实例bean时:Spring容器在创建的时候不会立刻将实例注入到spirng容器中,只有在调取的时候才会注入 (懒汉模式)
代码验证单例模式:这里我只是创建了ioc容器,单例这里调用了创建实例的方法。
代码验证多例模式:而多例模式则并没有调用这个创建方法
当调用获取实例的方法后才会调用创建实例的方法。
@Lazy:这注解就是专门为单例模式可以设置懒加载而创建的。只要添加这个注解。那么在单例模式只有调用获取实例时,才会去创建实例。
如下:如果只是生成ioc容器,是不会去调用创建实例bean的方法的
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)