【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
相关推荐
软件技术NINI6 分钟前
基于SpringBoot和Vue的摇滚乐鉴赏网站
vue.js·spring boot·后端·spring·html·毕业设计·毕设
Tsuki_tl23 分钟前
【总结】Redis五大数据类型应用场景及基本命令
数据库·redis·后端·缓存·缓存中间件·redis命令·redis 五大数据类型
后台模板学习25 分钟前
Go Web开发中任务调度框架的源码解析与高可用实现方案
开发语言·后端·golang
系统集成-鹰翔28 分钟前
ERP对接升级提示数据库迁移失败:SQLite逐版本事务到底回滚到哪一步
javascript·数据库·经验分享·后端
西瓜拿铁好喝29 分钟前
开源和闭源 AI 办公工具,分别适合谁
java·前端·数据库
IT_陈寒29 分钟前
深入理解SpringBoot:核心原理与最佳实践
前端·人工智能·后端
学长毕设31 分钟前
基于SpringBoot的校园礼服租赁系统的设计与实现
java·spring boot·后端
明天也要努力学习37 分钟前
深入理解 JVM 垃圾回收(GC)
java·jvm
golang学习记44 分钟前
IDEA 断点调试技巧:拖拽
java·ide·intellij-idea
Sayai1 小时前
Flink 日志解析任务性能优化实战:正则/Grok 预编译、Guava 缓存权重陷阱与 ES 写入隔离
java·大数据·性能优化·flink·实时计算