前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >bean的作用域和生命周期

bean的作用域和生命周期

作者头像
半月无霜
发布2023-03-03 15:22:49
2960
发布2023-03-03 15:22:49
举报
文章被收录于专栏:半月无霜

bean的作用域和生命周期

一、bean的作用域

Spring中,那些组成应用程序的主体及由 Spring IOC容器所管理的对象,被称之为 bean

简单地讲,bean就是由 IOC容器初始化、装配及管理的对象。

而作用域代表的 bean的创建存在方式,可以在哪里使用

我们分别可以使用以下这四种情况

scope取值

含义

创建对象的时机

singleton(默认)

在一个IOC容器中,这个 bean对象只有一个实例

IOC容器初始时创建单例 bean

prototype

在一个IOC容器中,这个 bean有多个实例

获取 bean的时候

request

每一次 http请求,都会创建一个 bean

每一次 http请求的时候

session

同一个 http session中,有且仅有一个 bean

产生新的 http session会话的时候

后面两种不做要求,仅用在基于 webSpring ApplicationContext环境


演示 singletonprototype的区别

代码语言:javascript
复制
 package com.banmoon.test.scope;
 
 import com.banmoon.test.User;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Scope;
 
 @Configuration
 public class BeanScope {
 
     @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
     @Bean(name = "user")
     public User user() {
         return new User(1, "banmoon");
     }
 
     public static void main(String[] args) {
         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanScope.class);
         User user = context.getBean(User.class);
         System.out.println(user);
         System.out.println("========== 分割线 ==========");
         // 再次获取user
         User user1 = context.getBean(User.class);
         System.out.println(user1);
     }
 
 }

单例启动,结果如下,两次对象地址打印是一致的

image-20230222092536815
image-20230222092536815

@Scope注解的值改为 prototype

代码语言:javascript
复制
 package com.banmoon.test.scope;
 
 import com.banmoon.test.User;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Scope;
 
 @Configuration
 public class BeanScope {
 
     @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
     @Bean(name = "user")
     public User user() {
         return new User(1, "banmoon");
     }
 
     public static void main(String[] args) {
         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanScope.class);
         User user = context.getBean(User.class);
         System.out.println(user);
         System.out.println("========== 分割线 ==========");
         // 再次获取user
         User user1 = context.getBean(User.class);
         System.out.println(user1);
     }
 
 }

可以看到他们的地址是不一致的

image-20230222092738236
image-20230222092738236

还有一点,注意上面 spring打印的 debug日志,可以清楚的看到 bean创建的时间节点, 单例 bean是在 IOC容器初始化后,马上就进行了创建 原型 bean是在每次创建时才进行创建,这也是每次获取不一致的原因所在

二、bean的生命周期

什么是 bean的生命周期,就是一个 bean从出生到死亡的过程,其中经历了哪些步骤,了解这些步骤,我们就可以更加清晰了解 bean的运行规律。

总的来说,bean的生命周期可以规划为下面这个步骤

  1. 初始化,也就是调用构造方法
  2. 通过 set方法进行赋值
  3. 处理 Aware系列接口,具体可以查看它的几个子接口具体是做什么的
  4. InitializingBean接口,调用其初始化方法
  5. 调用在 bean标签中指定的初始化方法
  6. 初始化完成,进行使用
  7. DisposableBean接口,调用其销毁方法
  8. 调用在 bean标签中指定的销毁方法
代码语言:javascript
复制
 package com.banmoon.test.lifecycle;
 
 import lombok.Getter;
 import org.springframework.beans.factory.BeanNameAware;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
 
 /**
  * @author banmoon
  */
 @Getter
 public class User implements InitializingBean, DisposableBean, BeanNameAware {
 
     private String name;
 
     public User() {
         System.out.println("1、调用无参构造进行创建");
     }
 
     public void setName(String name) {
         System.out.println("2、通过set方法进行设置属性");
         this.name = name;
     }
 
     @Override
     public void setBeanName(String s) {
         System.out.println("3、Aware系列接口,处理相关的逻辑");
     }
 
     @Override
     public void afterPropertiesSet() throws Exception {
         System.out.println("4、InitializingBean接口,初始化方法");
     }
 
     public void myInit() {
         System.out.println("5、在bean标签中指定的初始化方法");
     }
 
     @Override
     public void destroy() throws Exception {
         System.out.println("7、DisposableBean接口,销毁方法");
     }
 
     public void myDestroy() {
         System.out.println("8、在bean标签中指定的销毁方法");
     }
 
 }
代码语言:javascript
复制
 package com.banmoon.test.lifecycle;
 
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.Bean;
 
 public class Main {
 
     @Bean(name = "user", initMethod = "myInit", destroyMethod = "myDestroy")
     public User user() {
         User user = new User();
         user.setName("user");
         return user;
     }
 
     public static void main(String[] args) {
         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
         User bean = context.getBean("user", User.class);
         System.out.println("6、进行模拟使用:" + bean.getName());
         context.close();
     }
 
 }

代码比较简单,直接查看运行结果

image-20230223214903480
image-20230223214903480
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • bean的作用域和生命周期
    • 一、bean的作用域
      • 二、bean的生命周期
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档