Bean的作用域和生命周期
1.Bean的作用域(scope)
1.1基础概念
spring在默认情况下,其中Bean都是单例模式(默认都为单例scope=“singleton”),
单例模式:容器中创建唯一的实例化,在软件中一个永远唯一的对象,称为单例。
当scope=“prototype”(原型)就是多例模式,每次调用getBean()时,会创建对象,spring会创建多个实 例,也就是多例的。
1.2单例模式
1.Xml配置文件
创建一个dog对象,并且是单例的
<bean id="c" class="fyjz.com.spring.animal.Dog" scope="singleton"></bean>
2.Dog类
package fyjz.com.spring.animal;
public class Dog {
public void show(){
System.out.println("汪汪");
}
}
3.Test测试类
@Test
public void test04(){
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext4.xml");
Dog dog=ac.getBean("c",Dog.class);
Dog dog1=ac.getBean("c",Dog.class);
Dog dog2=ac.getBean("c",Dog.class);
System.out.println(dog==dog1);
}
4.测试结果
false
1.3多例模式
1.xml配置文件
与单例模式不一样的是scope=“prototype”
<bean id="c" class="fyjz.com.spring.animal.Dog" scope="prototype"/>
2.测试结果
Dog类和Test测试类与单例模式相同
true
2.延迟加载
2.1基本概念
当容器启动后立即创建实例,这称为“饿汉式”;
当容器启动后没有创建实例,在访问Bean对象时去创建对象,这称为“懒汉式(懒惰式)”;
默认为lazy-init="false"为“饿汉式”。
2.2饿汉式(单例)
因为默认情况下为“饿汉式”,所以饿汉式就是一般容器启动时运行的结果;单例模式下的“饿汉式”;
1.创建Dog类
package fyjz.com.spring.animal;
public class Dog {
public Dog(){
System.out.println("this is dog");
}
public void show(){
System.out.println("汪汪");
}
}
2.Xml配置文件
<bean id="b" class="fyjz.com.spring.animal.Dog" scope="singleton" lazy-init="false"/>
3.执行结果
this is dog
4.分析
在单例“饿汉式”的情况下,容器在加载类时会自动创建对象。spring创建对象默认为此方式。
2.3饿汉式(多例)
1.XML配置文件
将scope="singleton"改为scope=“prototype”;
<bean id="b" class="fyjz.com.spring.animal.Dog" scope="prototype" lazy-init="false"/>
2.执行结果
空的
3.分析
多例“饿汉式”模式下,spring在容器 启动时不会创建对象;
2.4懒汉式(单例)
1.XML配置文件
<bean id="b" class="fyjz.com.spring.animal.Dog" scope="singleton" lazy-init="true"/>
2.执行结果:
在启动容器时不会创建对象,在访问getBean对象时创建对象
2.5懒汉式(多例)
1.xml配置文件
<bean id="b" class="fyjz.com.spring.animal.Dog" scope="prototype" lazy-init="true"/>
2.执行结果
执行结果和单例模式下的懒汉式一样,在启动容器时不会创建对象,在访问getBean对象时创建对象。
2.6总结
单例模式有延迟加载
多例模式没有延迟加载(不存在饿汉式和懒汉式)
3.Bean的生命周期
Bean的生命周期(单例/多例):
Spring中的Bean对象,由Spring控制对象的创建和销毁,这个这个过程称为“Bean对象的生命周期”。
创建:如果是单例模式:scope=“singleton”,spring在创建Bean对象时,进行初始化,如果设置了init-method属性后,则在创建对象后调用初始化方法,每次调用getBean()时返回的都是同一个对象。
销毁:在spring容器关闭的时候(调用spring容器中的close()方法即可关闭容器),spring会自动销毁单例模式,如果指定了destroy-method属性,则会在销毁时执行该销毁方法;
1.单例模式下
1.Xml配置文件
<bean id="d" class="fyjz.com.spring.animal.Dog" init-method="initdog" destroy-method="desDog" scope="singleton"/>
2.Dog类
package fyjz.com.spring.animal;
public class Dog {
public Dog(){
System.out.println("this is dog");
}
public void initdog(){
System.out.println("dog初始化");
}
public void show(){
System.out.println("汪汪");
}
public void desDog(){
System.out.println("该bean对象销毁了");
}
}
3.测试
public class Testdemo2 {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext5.xml");
Dog d=ac.getBean("d",Dog.class);
d.show();
ac.close();
}
}
4.测试结果
this is dog
dog初始化
汪汪
该bean对象销毁了
2.多例模式下
1.Xml配置文件
<bean id="d" class="fyjz.com.spring.animal.Dog" init-method="initdog" destroy-method="desDog" scope="singleton"/>
Dog类和测试类与单例模式下的相同
2.运行结果
this is dog
dog初始化
汪汪
3.总结
多例模式不会调用"销毁"方法。
如果是单例:创建Bean对象——>Bean的初始化——>Bean处理业务——>Bean对象销毁
如果是多例:创建Bean对象——>Bean的初始化——>Bean处理业务
4.延迟加载实例化
1.XMl配置文件
懒汉式:
<bean id="d" class="fyjz.com.spring.animal.Dog" init-method="initdog" destroy-method="desDog" lazy-init="true" />
2.执行结果
this is dog
dog初始化
汪汪
该bean对象销毁了
3.总结
饿汉式/懒汉式:创建Bean对象——>Bean的初始化——>Bean处理业务——>Bean对象销毁