【Spring 原理】Bean 的作用域与生命周期

文章目录

一、Bean的作用域

1.1 概念

在Spring IoC&DI,Spring 是通过以下方式管理对象的。

  1. 通过@Controller , @Service , @Repository , @Component , @Configuration , @Bean 来声明Bean对象。
  2. 通过 ApplicationContext 或者 BeanFactory 来获取对象
  3. 通过@Autowired , Setter 方法或者构造方法等来为应用程序注入所依赖的Bean对象。

  1. 通过@Bean 声明bean , 把bean存在Spring容器中
java 复制代码
@Component
public class DogBeanConfig {
	@Bean
	public Dog dog(){
		Dog dog = new Dog();
		dog.setName("旺旺");
		return dog;
	}
}
  1. 从Spring容器中获取Bean
java 复制代码
@SpringBootApplication
public class SpringIocApplication {
	public static void main(String[] args) {
		//获取Spring上下文对象
		ApplicationContext context = SpringApplication.run(SpringIocApplication.class, args);
		//从Spring上下文中获取对象
		Dog dog = context.getBean(Dog.class);
		System.out.println(dog);	
	}
}

也可以通过在代码中直接注入ApplicationContext的方式来获取Spring容器

java 复制代码
@SpringBootTest
class DemoApplicationTests {
	@Autowired
	private ApplicationContext applicationContext; //Spring 容器

	@Test
	void contextLoads() {
		DogBean dog1 = applicationContext.getBean(DogBean.class);
		System.out.println(dog1);	
	}
}

观察运行结果:

发现输出的bean对象地址值是一样的,说明每次从Spring容器中取出来的对象都是同一个。这也是"单例模式"

单例模式:确保一个类只有一个实例,多次创建也不会创建出多个实例。

默认情况下,Spring容器中的bean都是单例的,这种行为模式,我们就称之为Bean的作用域。

Bean 的作用域是指 Bean 在 Spring 框架中的某种行为模式。

1.2 Bean的作用域

在Spring中支持6种作用域,后4种在Spring MVC环境才生效

  1. singleton:单例作用域
  2. prototype:原型作用域(多例作用域)
  3. request:请求作用域
  4. session:会话作用域
  5. Application: 全局作用域
  6. websocket:HTTP WebSocket 作用域
作用域 说明
singleton 每个Spring IoC容器内同名称的bean只有一个实例(单例)(默认)
prototype 每次使用该bean时会创建新的实例(非单例)
request 每个HTTP 请求生命周期内, 创建新的实例(web环境中, 了解)
session 每个HTTP Session生命周期内, 创建新的实例(web环境中, 了解)
application 每个ServletContext生命周期内, 创建新的实例(web环境中, 了解)
websocket 每个WebSocket生命周期内, 创建新的实例(web环境中, 了解)

二、Bean的生命周期

2.1 概念

生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期。 Bean 的生命周期分为以下5个部分:

  1. 实例化(为Bean分配内存空间)
  2. 属性赋值(Bean注入和装配,比如@AutoWired )
  3. 初始化
    a. 执行各种通知,如 BeanNameAware , BeanFactoryAware ,ApplicationContextAware 的接口方法。
    b. 执行初始化方法
    ▪ xml定义init-method
    ▪ 使用注解的方式 @PostConstruct
    ▪ 执行初始化后置方法( BeanPostProcessor )
  4. 使用Bean
  5. 销毁Bean
    a. 销毁容器的各种方法,如 @PreDestroy , DisposableBean 接口方法,destroymethod。

实例化和属性赋值对应构造方法和setter方法的注入。 初始化和销毁是用户能自定义扩展的两个阶段,可以在实例化之后,类加载完成之前进行自定义"事件"处理。

执行流程如下图所示:

2.1 代码演示

java 复制代码
@Component
public class BeanLifeComponent implements BeanNameAware {

	private UserComponent userComponent;

	public BeanLifeComponent() {
		System.out.println("执行构造函数");
	}

	@Autowired
	public void setUserComponent(UserComponent userComponent) {
		System.out.println("设置属性userComponent");
		this.userComponent = userComponent;
	}

	@Override
	public void setBeanName(String s) {
		System.out.println("执行了 setBeanName 方法:" + s);
	}


	@PostConstruct
	public void postConstruct() {
		System.out.println("执行 PostConstruct()");
	}
	public void use() {
		System.out.println("执行了use方法");
	}


	@PreDestroy
	public void preDestroy() {
		System.out.println("执行:preDestroy()");
	}
}

通过运行结果观察

  1. 先执行构造函数
  2. 设置属性
  3. Bean初始化
  4. 使用Bean
  5. 销毁Bean
相关推荐
程序员Terry12 小时前
博客系统全文搜索实战:用 Elasticsearch 告别 MySQL LIKE 查询
后端·elasticsearch
漓漾li12 小时前
每日面试题(2026-05-20)- GO AI agent全栈
后端·架构·go
XS03010612 小时前
并发编程二
java·开发语言
雪度娃娃12 小时前
转向现代C++——优先选用限定作用域的枚举型别,而非不限作用域的枚举型别
java·jvm·c++
不是光头 强12 小时前
Java 后端实战进阶:从踩坑到架构的系统化笔记
java·笔记·架构
ID_1800790547312 小时前
企业级淘宝评论 API最简说明,JSON 返回示例
java·服务器·前端
Plan-C-13 小时前
二叉树的遍历
java·数据结构·算法
历程里程碑13 小时前
54 深入解析poll多路复用技术
java·linux·服务器·开发语言·前端·数据结构·c++
无限进步_13 小时前
【C++】可变参数模板与emplace系列
java·c++·算法
逐光老顽童13 小时前
Java 内存模型深度解析与 JVM 调优实战指南
java·架构