文章目录
本博客demo源码地址
https://github.com/suchahaerkang/spring-annotation.git
1 @Scope
注意:
- @Scope 作用域有四种:
- singleton:单实例(默认),在IOC容器创建的时候创建对象和初始化,并且只创建一次,后面每次使用的都是同一实例1
- prototyp:多实例,在IOC容器创建的时候不会去创建,等调用对象的时候才去创建和初始化,多实例是每调用一次就回创建一次对象
- request:每个请求创建一个对象
- session:每个会话创建一个对象
1.1 代码检验@Scope注解默认作用域是什么
首先创建一个MainConfig2的配置类,然后通过@Scope注解配置组件Person的作用域
@Configuration
public class MainConfig2 {
@Scope
@Bean("person")
public Person person(){
return new Person("张三", 18);
}
}
测试用例代码如下
@Test
public void test03(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
Person person1 = (Person) applicationContext.getBean("person");
Person person2 = (Person) applicationContext.getBean("person");
System.out.println(person1 == person2);
}
运行结果
说明@Scope注解默认为单实例
1.2 代码检验作用域为单实例的时候什么时候开始创建实例
在上面的配置文件中打印一句“开始创建Person实例…”
@Configuration
public class MainConfig2 {
@Scope
@Bean("person")
public Person person(){
System.out.println("开始创建Person实例....");
return new Person("张三", 18);
}
}
测试用例代码
@Test
public void test03(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
/*Person person1 = (Person) applicationContext.getBean("person");
Person person2 = (Person) applicationContext.getBean("person");
System.out.println(person1 == person2);*/
}
运行结果
说明单实例是在IOC容器创建的时候创建和初始化的
1.3 代码验证多实例prototype的特性和实例创建时间
在配置文件中将作用域改为多例prototype
@Configuration
public class MainConfig2 {
@Scope("prototype")
@Bean("person")
public Person person(){
System.out.println("开始创建Person实例....");
return new Person("张三", 18);
}
}
测试用例
@Test
public void test03(){
//创建IOC容器
System.out.println("开始创建IOC容器...");
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
System.out.println("第一次从容器中获取Person的实例...");
Person person1 = (Person) applicationContext.getBean("person");
System.out.println("第二次从容器中获取Person的实例...");
Person person2 = (Person) applicationContext.getBean("person");
System.out.println("两个实例对比结果:");
System.out.println(person1 == person2);
}
运行结果
因为@Scope默认的是单实例,但是单实例是在容器创建的时候创建的,如果我不想让单实例在容器创建的时候创建,希望在调用的时候进行创建,那么我们改怎么配置呢? 下面我们就引入了另外一个注解@Lazy (懒加载)
2 @Lazy
懒加载的作用就是会让单实例的组件在容器创建的时候不创建和初始化,等到用到实例的时候才去创建和初始化
在配置文件中加上@Lazy注解
@Configuration
public class MainConfig2 {
@Lazy
@Scope
@Bean("person")
public Person person(){
System.out.println("开始创建Person实例....");
return new Person("张三", 18);
}
}
测试用例
@Test
public void test03(){
//创建IOC容器
System.out.println("开始创建IOC容器...");
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
System.out.println("第一次从容器中获取Person的实例...");
Person person1 = (Person) applicationContext.getBean("person");
System.out.println("第二次从容器中获取Person的实例...");
Person person2 = (Person) applicationContext.getBean("person");
System.out.println("两个实例对比结果:");
System.out.println(person1 == person2);
}
运行结果