【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
相关推荐
*小海豚*2 小时前
在linux服务器上DNS正常,但是java应用调用第三方解析域名报错
java·linux·服务器
我爱加班、、2 小时前
Websocket能携带token过去后端吗
前端·后端·websocket
撩得Android一次心动2 小时前
Android LiveData 全面解析:使用Java构建响应式UI【源码篇】
android·java·android jetpack·livedata
组合缺一2 小时前
Solon AI (Java) v3.9 正式发布:全能 Skill 爆发,Agent 协作更专业!仍然支持 java8!
java·人工智能·ai·llm·agent·solon·mcp
MSTcheng.2 小时前
【C++】C++11新特性(二)
java·开发语言·c++·c++11
一 乐2 小时前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
KIKIiiiiiiii2 小时前
微信个人号API二次开发中的解决经验
java·人工智能·python·微信
80530单词突击赢2 小时前
SpringBoot整合SpringMVC全解析
java·spring boot·后端
vx1_Biye_Design2 小时前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven