注解@Scope可以指定下面四种类型:
singleton: 单实例(默认),IOC容器启动会调用方法创建对象放到IOC容器中,以后每交获取就是直接从容器中拿。
prototype: 多实例,IOC容器启动并不会去调用方法创建对象放在容器中,而是每次获取的时候才会调用方法创建对象。
request: 主要针对WEB应用,同一次请求创建一个实例
session: 同一个session创建一个实例(后面两个用得不多,了解即可)
@Scope如果不指定类型,默认是单实例。下面的代码指定Product为多实例。
@Scope("prototype") public Product product(){ return new Product(); }
懒加载注解@Lazy针对的是单实例bean,单实例bean默认在容器启动的时候创建对象;标注该注解后容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
1、测试单实例bean
Product类
public class Product { public Product(){ System.out.println("新建对象"); } }
配置类:这里没有指定@Scope
@Configuration public class PrototypeConfig { @Bean public Product product(){ return new Product(); } }
测试:同时从容器中获取两个name为product对象,比较两个对象是否相等
@Test public void test1(){ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(PrototypeConfig.class); //工厂Bean获取的是调用getObject创建的对象a System.out.println("获取对象"); Object bean1 = applicationContext.getBean("product"); Object bean2 = applicationContext.getBean("product"); System.out.println(bean1 == bean2); }
从运行结果可以看出,在获取对象之前,spring已经初始化了该对象。打印出true,表明两次获取的对象是相同对象。
添加@Lazy
@Configuration
public class LazyConfig {
@Bean
@Lazy
public Product product(){
return new Product();
}
}
测试运行
@Test public void test2(){ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(LazyConfig.class); //工厂Bean获取的是调用getObject创建的对象a System.out.println("获取对象"); Object bean1 = applicationContext.getBean("product"); Object bean2 = applicationContext.getBean("product"); System.out.println(bean1 == bean2); }
从结果可以看出Product的初始化是在获取的时候完成的类的初始化
2、测试多实例bean
通过@Scope("prototype")指定为一个多实例bean
@Configuration
public class PrototypeConfig1 {
@Bean
@Scope("prototype")
public Product product(){
return new Product();
}
}
测试运行下面的代码
@Test
public void test3(){
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(PrototypeConfig1.class);
//工厂Bean获取的是调用getObject创建的对象a
System.out.println("获取对象");
Object bean1 = applicationContext.getBean("product");
Object bean2 = applicationContext.getBean("product");
System.out.println(bean1 == bean2);
}
从结果可以看出,每次获取bean都需要重新创建。