本文知识点来源于尚硅谷,感谢尚硅谷为广大学子提供的优质教育资源,感谢各位老师热情指导,本文仅作为学习笔记使用,记录学习心得,如有不适,请联系作者。
我们注册到IOC容器的组件默认是单实例的
验证:
/**
* 配置类==配置文件xml
* @author Administrator
*
*/
@Configuration //告诉Spring这是一个配置类
public class MainConfig2 {
/**
* 给容器注册一个bean,类型为返回值类型,id默认是方法名
* 如果想指定id 可以写作@Bean("person2")
*
* @return
*/
@Bean
public Person person() {
System.out.println("创建person对象");
return new Person("李四",18,"男");
}
}
测试类:
public class MainTest_IOC {
@Test
public void test() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
System.out.println("IOC容器启动");
Person person = (Person) applicationContext.getBean("person");
Person person2 = (Person) applicationContext.getBean("person");
//验证是否是单实例的
System.out.println(person == person2);
}
}
输出:
创建person对象
IOC容器启动
true
我们如何改变这个默认作用范围呢?
@Scope
配置类中加上@Scope注解并设置多实例
@Bean
@Scope(value = "prototype")
public Person person() {
System.out.println("创建person对象");
return new Person("李四",18,"男");
}
执行测试类输出:
IOC容器启动
创建person对象
创建person对象
false
由以上两次验证我们可以总结:
@Scope 调整作用域:
- singleton 单实例(默认),ico启动的时候创建对象放到容器,以后每次获取就是直接从容器中拿(map.get())。
- prototype 多实例,ioc容器启动不会调用方法创建对象放在容器中,每次获取的时候才会调用方法创建对象。
另外在web环境下还有(极少使用): - request:同一次请求创建一个实例。
- session:同一个 session创建一个实例。
@Lazy懒加载
配置类如下:
@Bean//默认单实例Bean
@Lazy
public Person person() {
System.out.println("创建person对象");
return new Person("李四",18,"男");
}
测试类不变
@Test
public void test() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
System.out.println("IOC容器启动");
Person person = (Person) applicationContext.getBean("person");
Person person2 = (Person) applicationContext.getBean("person");
//验证是否是单实例的
System.out.println(person == person2);
}
输出:
IOC容器启动
创建person对象
true
总结:
@Lazy懒加载:
针对单实例Bean,容器启动的时候先不创建对象,在第一次获取Bean的时候创建对象,并初始化。
由测试类我们也可以证实,对于单实例Bean,我们获取了两次,单只打印了一次“创建person对象”也能佐证单实例bean只创建一次。