【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
相关推荐
沙蒿同学8 分钟前
我把架构约定编译成了会变红的测试:Wails v2 + Go + Vue3 桌面脚手架实战
前端·后端·github
cxoptics9 分钟前
偏振片(起偏器/检偏器)怎么区分?
java
量化分析码农10 分钟前
【Python量化数据工程实战 #01】拉下来的行情全是"脏数据"?停牌、跳空、异常值一站式清洗
后端
专业程序开发源12 分钟前
springboot篮球联赛管理系统13635-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·django·php·课程设计
StevenLdh29 分钟前
第四期 · 云端同步与冲突仲裁:离线可写、多端一致的工程解法
java·微信小程序
事已至此先睡覺吧39 分钟前
第三篇:Java 流程控制详解:条件判断、循环与跳转语句
java·开发语言
毕业设计70340 分钟前
(免费领源码) SpringBoot 游戏交易平台17600-java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
java·spring boot·mysql·决策树·mybatis·idea·推荐算法
一 乐1 小时前
自习室座位预约管理系统|基于springboot + vue自习室座位预约管理系统(源码+数据库+文档)
java·vue.js·spring boot
行百里er1 小时前
轻量级 Spring 监测工具——Spring Insight 发布了
spring boot·后端·监控
此时不提桶,更待何时1 小时前
02-02-B-AQS与JUC锁面试与生产事故实战
java