目录
1、容器Bean的Scope范围
2、Bean对象的生命周期
1、容器Bean的Scope范围
spring容器在非WEB环境下bean的范围包括prototype(多例)、singleton(单例)2种,spring容器bean的默认scope是singleton。 单例会存在线程安全问题,多例则没有此问题。单例范围bean在IOC容器启动时实例化,多例在使用时(getBean)或对象注入时实例化。
演示示例:Course设置了单例,Student设置了多例,在容器启动后,只实例化了Course,Course全局唯一,在使用时Context.getBean("student") 才实例化Student,并且每次实例化的对象都是新的
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="course" class="com.text.entity.Course"><constructor-arg name="name" value="语文"/></bean><bean id="student" class="com.text.entity.Student" scope="prototype"><property name="name" value="张三"/><property name="age" value="20"/><property name="course" ref="course"/></bean>
</beans>
实体类:
package com.text.entity;
public class Course {private String name;//课程名称public Course() {}public Course(String name) {System.out.println("【课程bean】singleton范围的bean在IOC容器启动时初始化" + this);this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
package com.text.entity;
public class Student {private String name;private int age;private Course course;public Student() {}public Student(String name, int age, Course course) {this.name = name;this.age = age;this.course = course;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Course getCourse() {return course;}public void setCourse(Course course) {this.course = course;}
}
测试类:
package com.text.entity;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {String configLocation = "classpath:applicationContext.xml";//执行后输出:【课程bean】singleton范围的bean在IOC容器启动时初始化com.text.entity.Course@91161c7ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);System.out.println("==========IOC容器完成初始化==========");Course course1 = context.getBean("course",Course.class);Course course2 = context.getBean("course",Course.class);System.out.println(course1 == course2);//scope=singleton 返回trueStudent student1 = context.getBean("student",Student.class);Student student2 = context.getBean("student",Student.class);System.out.println(student1 == student2);//scope=prototype 返回falseSystem.out.println(student1.getCourse() == student2.getCourse());//课程类是单例,公用一个课程示例,返回true}
}
输出结果:
【课程bean】singleton范围的bean在IOC容器启动时初始化com.text.entity.Course@91161c7
==========IOC容器完成初始化==========
true
false
true
2、Bean对象的生命周期
IOC容器的bean经历如下生命周期阶段:
- 对象实例化(执行构造方法)
- 注入属性(context.xml 声明的property属性)
- 执行init-method初始化方法(context.xml声明的init-method)
- IOC容器销毁,执行destroy-method方法(context.xml声明的init-method)
演示示例:
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="course" class="com.text.entity.Course" init-method="init" destroy-method="destroy"><constructor-arg name="name" value="语文"/></bean><bean id="student" class="com.text.entity.Student" scope="prototype" ><property name="name" value="张三"/><property name="age" value="20"/><property name="course" ref="course"/></bean>
</beans>
实体类:
package com.text.entity;
public class Course {private String name;//课程名称public Course() {}public Course(String name) {System.out.println("【课程bean】singleton范围的bean在IOC容器启动时初始化" + this);this.name = name;}public void init() {System.out.println("模拟初始化init方法");}public void destroy() {System.out.println("模拟对象销毁方法");}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
测试类:
package com.text.entity;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {String configLocation = "classpath:applicationContext.xml";ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);System.out.println("==========IOC容器完成初始化==========");System.out.println("业务代码执行...");((ClassPathXmlApplicationContext)context).registerShutdownHook();//销毁IOC容器}
}
输出结果:
【课程bean】singleton范围的bean在IOC容器启动时初始化com.text.entity.Course@91161c7
模拟初始化init方法
==========IOC容器完成初始化==========
业务代码执行...
模拟对象销毁方法