IOC(bean的作用域与生命周期)
单例和多例
1 . 什么是单例和多例
单例 (singleton):
多例 (prototype):每个请求用一个新的对象来处理。
如果一个bean被声明为单例的时候,在处理多次请求的时候,
在spring容器里只实例化出一个bean,后续的请求都公用这个对象,
这个对象会保存在一个map里面。
但是对于原型(prototype)bean来说,当每次请求来的时候,会直接实例化新的bean,
没有缓存以及缓存查询的过程。
2 . 为什么用单例和多例
之所以用单例:是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存;
之所以用多例:是为了防止并发问题;即一个请求改变了对象的状态,
此时对象又处理另一个请求,而之前请求对对象状态的改变导致了
对象对另一个请求做了错误的处理;
用单例和多例的标准只有一个:
当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例;
在 Spring 中可以通过配置 bean 标签的 scope 属性来指定 bean 的作用域范围:
| 取值 | 含义 | 创建对象的时机 | 默认值 |
|---|---|---|---|
| singleton | 在 IOC 容器中,这个 bean 的对象始终为单实例 | IOC 容器初始化时 | 是 |
| prototype | 这个 bean 在 IOC 容器中有多个实例 | 获取 bean 时 | 否 |
如果是在WebApplicationContext环境下还会有另外两个作用域(但不常用):
| 取值 | 含义 |
|---|---|
| request | 在一个请求范围内有效 |
| session | 在一个会话范围内有效 |
<!--
scope:设置bean的作用域
scope:"singleton/prototype"
singleton(单例):表示获取该bean所对应的对象都是同一个 (默认,用的也最多)
prototype(多例):表示获取该bean所对应的对象都不是同一个
-->
<bean id="student" class="com.atguigu.spring.pojo.Student" scope="prototype"></bean>
bean生命周期
1 . bean的生命周期清单
-
bean 对象创建(调用无参构造器)
-
给 bean 对象设置属性(调用属性对应的 setter 方法)
-
bean 对象初始化之前操作(由 bean 的后置处理器postProcessBeforInitalization负责)
-
bean 对象初始化(需在配置 bean 时指定初始化方法)
-
bean 对象初始化之后操作(由 bean 的后置处理器负责)
-
bean 对象就绪可以使用
-
bean 对象销毁(需在配置 bean 时指定销毁方法)
-
IOC 容器关闭
注意:若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
若bean的作用域为多例时,生命周期的前三个步骤会在获取bean的时候执行
package com.atguigu.spring.pojo;
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
public User() {
System.out.println("生命周期1:实例化");
}
public User(Integer id, String username, String password, Integer age) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
System.out.println("生命周期2:依赖注入(为属性赋值)");
this.id = id;
}
....
....
public void initMethod(){
System.out.println("生命周期3:初始化");
}
public void destroyMethod(){
System.out.println("生命周期4:销毁");
}
}
<!--
设置初始化和销毁的过程,需要通过bean标签的属性来进行指定
销毁的方法是当前IOC容器关闭的时候才会销毁
-->
<bean id="user" class="com.atguigu.spring.pojo.User" init-method="initMethod" destroy-method="destroyMethod">
<property name="id" value="1"></property>
<property name="username" value="admin"></property>
<property name="password" value="123456"></property>
<property name="age" value="23"></property>
</bean>
/**
* ①实例化--> ②依赖注入 -->③初始化:需要通过bean的init-method属性指定初始化方法--->IOC容器关闭销毁:destroy-method
*/
浙公网安备 33010602011771号