Bean的作用域和生命周期
1. Bean的作用域
1.1 什么是Bean的作用域
限定程序中变量的可用范围叫做作用域。而Bean的作用域是指Bean 在Spring整个框架中的某种行为模式,比如singleton单例作用域,就表示Bean在整个Spring中只有一份,他是全局共享的,当某个人对象修改后,另一个人拿到就是修改之后的Bean。
1.2 Bean的6种作用域
在Spring初始化一个Bean的一个实例时,同时会指定该实例的作用域。Spring有6种作用域,最后4种是基于Spring MVC生效的:
singleton——单例作用域
该作用域下的Bean,在一个IoC容器里面只存在一个实例,获取Bean都是针对对同一个对象。是Spring当中时默认的作用域。
prototype——多例作用域
该作用域下的Bean,对他每次请求都会创建一个新的实例,获取到的Bean都是新的对象。
request——请求作用域
每次http请求都会创建新的Bean实例,类似于prototype。限定在Spring MVC中使用。
session——会话作用域
在一个http session中,定义一个Bean实例。使用场景:用户会话的共享Bean,比如记录一个用户的登录信息。限定在Spring MVC中使用。
application——全局作用域(了解)
在⼀个http servlet Context中,定义⼀个Bean实例。场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息。备注:限定SpringMVC中使⽤。
websoccket——HTTP WebSocket作用域(了解)
在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例。场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,直到WebSocket结束都是同⼀个Bean。备注:限定Spring WebSocket中使⽤。
1.3 设置作用域
使用@Scope进行设置。有两种形式:
- 直接设置值:@Scope(“prototype”)
- 使⽤枚举设置@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class SetUser {
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)//设置作用域为多例作用域
@Bean(name = "user")
public User setUser(){
User user = new User();
user.setId(1);
user.setName("张三");
return user;
}
}
2. Bean的生命周期
2.1 Spring 执行流程
2.2 bean 的生命周期
- 实例化(分配内存空间)
- 设置属性(DI注入)
- 初始化
3.1 执行各种通知
3.2 初始化的前置方法
3.3 初始化方法
3.4 初始化的后置方法
- 使用bean
- 销毁bean
2.3 演示bean的生命周期
BeanLifeComponent:
//@Component
public class BeanLifeComponent implements BeanNameAware {
@Override
public void setBeanName(String s) {
System.out.println("执行了 Bean Name 通知:"+s);
}
/*
方法名随意定义
xml中init-method 指定的方法
*/
public void initMethod(){
System.out.println("执行了 init method 方法");
}
@PostConstruct
public void myPostConstruct(){
System.out.println("执行了PostConstruct方法");
}
/*
销毁前执行方法
*/
@PreDestroy
public void myPreDestroy(){
System.out.println("执行了PreDestroy方法");
}
public void use(){
System.out.println("执行了 use 方法");
}
}
spring-config.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"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="beanlife" class="com.mytest.controller.BeanLifeComponent" init-method="initMethod"></bean>
</beans>
main:
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
BeanLifeComponent component = context.getBean("beanlife",BeanLifeComponent.class);
component.use();
context.destroy();
}
执行结果:
结果分析: