Spring 与组件注入相关的注解之 @Scope 和 @Lazy

11 篇文章 0 订阅
11 篇文章 0 订阅
前言:

通过上一个demo,又进一步体会到了如何实现 spring 组件的注入。下面对注入到 IOC 容器中的组件的作用域作进一步说明。另外,这里还涉及到注入到容器中的 bean 的生命周期的问题。在后续博客中还会针对 bean 的生命周期作相关介绍。

实验:
  1. 准备配置类,注入 Person 组件:
package com.uestc.auto.xiaoxie.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.uestc.auto.xiaoxie.bean.Person;

@Configuration // 配置类
public class SpringConfig1 {
   @Bean
   public Person person(){
   	// System.out.println("向容器中添加Person组件");
   	return new Person("kristina", 24);
   }
}
  1. 编写测试方法:为简化代码,将 ApplicationContext 的创建和容器的关闭分别放在 junit 的 before() 和 after() 方法中,这样不必在每一个单元测试方法中写重复的代码。
private AnnotationConfigApplicationContext context;
	
	@Before
	public void beforeMethod(){
		context = new AnnotationConfigApplicationContext(SpringConfig1.class);
	}
	@Test
	public void testScope() {
		Person person = (Person)context.getBean("person");
		Person person2 = (Person)context.getBean("person");
		System.out.println(person == person2); // true,即默认创建的 bean 是单例的
	}

	@After
	public void afterMethod(){
		context.close();
	}
  1. 修改配置类:在注入 Person 对象的时候,通过 @Scope 注解的 scopeName 属性指定 bean 的作用域为多例。再次进行测试,发现两次获取的 person 并非同一个对象了。
	@Bean
   @Scope(scopeName=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
   public Person person(){
   		System.out.println("向容器中添加Person组件");
   		return new Person("kristina", 24);
   }

由下图可以看出,scopeName 四种不同的取值对应了四种不同的作用域:

scopeName的取值对应的含义
ConfigurableBeanFactory.SCOPE_PROTOTYPE多例
ConfigurableBeanFactory.SCOPE_SINGLETON默认值,单例
WebApplicationContext.SCOPE_REQUEST如果设置为此值的话,在web应用中一个请求会是一个对象。
WebApplicationContext.SCOPE_SESSION如果设置为此值的话,在web应用中一个session会话会是一个对象。
  1. 下面对单实例和多实例对象的创建时机进行测试:为更好地看到实验效果,在配置类的 public Person person() 方法体中多添加一句 sysout 语句:System.out.println(“向容器中添加Person组件”)。然后,将单元测试方法(testScope)的方法体注释掉,即只创建 ApplicationContext 对象。
    在单例模式下,重新运行,发现在创建 context 对象的时候就会调用 person() 方法,注入 Person 组件;
    改为多例模式,重新运行,发现创建 context 对象的时候并不会去调用 person() 方法,而是在真正 context.getBean() 的时候才会注入 Person 组件。
即在单例模式下,在IOC容器初始化的时候就会创建对象。后面用的时候,拿到的也都是同一个对象;
而在多例模式下,IOC容器初始化的时候并不会创建对象,在 getBean() 的时候才会创建相应的对象。
  1. @Lazy 注解:
    上面也提到了,在单例模式下,IOC容器初始化的时候就会创建相应的bean;懒加载(@Lazy)可以实现的效果:用的时候(getBean())才去创建相应的bean,而不是容器初始化的时候就创建。
    @Lazy
//	@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
   	@Bean 
   	public Person person(){
   		System.out.println("向容器中添加Person组件");
   		return new Person("Arianna", 28);
   	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值