前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >谈谈 Spring 中 Bean 的生命周期?(让你瞬间通透~)

谈谈 Spring 中 Bean 的生命周期?(让你瞬间通透~)

作者头像
IT大咖说
发布2024-06-18 16:22:03
1970
发布2024-06-18 16:22:03
举报
文章被收录于专栏:IT大咖说IT大咖说
Bean的生命周期
  • 概括
  • 图解
  • 代码示例
  • 初始化代码
  • 初始化的前置方法和后置方法(重写)
  • Spring启动类
  • 执行结果
  • 经典面试问题
  • 总结

◆1Bean的生命周期

◆1.1、概括

Spring中Bean的生命周期就是Bean在Spring中从创建到销毁的整个过程,主要分为以下5个部分:

1.实例化: 给Bean分配内存空间(对应JVM中的“加载”,这里只是分配了内存);

2.设置属性: 进行Bean的注入和装配;

3.初始化:

  • 执行各种通知;
  • 执行初始化的前置工作;
  • 进行初始化工作(使用注解 @PostConstruct 初始化 或者 使用(xml)init-method 初始化, 前者技术比后者技术先进~);
  • 执行初始化的后置工作;

4.使用Bean

5.销毁Bean

值得注意的是:实例化和初始化是两个完全不同的过程,前者只是给Bean分配内存空间,而后者则是将程序执行权从系统级别转到用户级别,执行用户添加的业务代码。

◆1.2、图解

下图以买房、盖房、入住、卖房为栗子,方便理解~

图片

◆2代码示例

◆2.1、初始化代码

以下,我将在Spring中,演示Bean的生命周期:

创建一个类,名为BeanLifeComponent(这个名字是自定义的), 写下初始化的各类操作:

代码语言:javascript
复制
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
 
@Component
public class BeanLifeComponent implements BeanNameAware {
 
    //执行各种通知
    @Override
    public void setBeanName(String s) {
        System.out.println("执行了通知");
    }
 
    //初始化的前置和后置方法不能写在这个Bean中!
 
    //执行初始化方法(注解)
    @PostConstruct
    public void postConstruct() {
        System.out.println("通过注解 @PostConstruct 执行了初始化方法");
    }
 
    //使用
    public void useBean() {
        System.out.println("使用Bean");
    }
 
    //销毁
    @PreDestroy
    public void preDestory() {
        System.out.println("执行了销毁方法");
    }
 
}

注意:

1.这里不能写出实例化过程,因为给Bean分配内存对应JVM类加载过程; 2.当前这个Bean中不能写初始化的前置方法和后置方法,否则不会执行,因为初始化的前置方法和后置方法是需要继承BeanPostProcessor接口,重写两个方法实现的, 并且是为所有 Bean 服务的,而非为某一个 Bean 服务的,若写在一个某一个Bean中,则不会执行。

◆2.2、初始化的前置方法和后置方法(重写)

另外再创建一个类(避免在一个Bean中),自定义名为 MyBeanPostProcessor ,接着继承BeanPostProcessor接口,重写初始化的前置方法和后置方法,如下代码:

代码语言:javascript
复制
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
 
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
 
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行了初始化的前置方法");
        return bean;
    }
 
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行了初始化的后置方法");
        return bean;
    }
}

◆2.3、Spring启动类

最后在Spring启动类中获取Bean对象,如下代码:

代码语言:javascript
复制
import com.demo3.component.BeanLifeComponent;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App3 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
 
        //获取Bean
        BeanLifeComponent beanLifeComponent =
                context.getBean("beanLifeComponent", BeanLifeComponent.class);
        //使用Bean
        beanLifeComponent.useBean();
        //销毁Bean
        context.destroy();
    }
}

为什么这里不使用 ApplicationContext 而是使用它的子类 ClassPathXmlApplicationContext 呢?因为 ClassPathXmlApplicationContext 中有destroy销毁方法(用来销毁容器,容器销毁了,Bean自然就没了),而ApplicationContext 中没有这个销毁方法,演示的时候,就体现不出来了。

◆2.4、执行结果

图片

从执行结果来看,符合咱们预期~

◆2.5、经典面试问题

那么是否可以先执行 初始化 再执行 设置属性 呢?不可以!想象一下,如果在初始化的方法中要用你设置的属性,就会引发空指针异常,如下代码:

代码语言:javascript
复制
@Controller
public class StudentController {
 
    //属性注入
    @Autowired
    private Student student;
 
    //初始化
    @PostConstruct
    public void init() {
        student.setName("周杰伦");
    }
 
}

如果你先执行了初始化 init() 方法,而 init() 方法中需要使用属性注入后得到的Student对象,那么此时还没有注入就进行修改,就会引发空指针异常。

◆3总结

Spring中Bean的生命周期就是Bean在Spring中从创建到销毁的整个过程。

主要就是由:

  1. 实例化
  2. 设置属性:进行Bean的注入和装配
  3. 初始化
  4. 使用Bean
  5. 销毁Bean

这五步构成,并且任何顺序都不可以随意调换。

Bean的执行流程属于常见面试题,一定要在理解的基础上牢记!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT大咖说 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ◆1Bean的生命周期
  • ◆1.1、概括
  • ◆1.2、图解
  • ◆2代码示例
  • ◆2.1、初始化代码
  • ◆2.2、初始化的前置方法和后置方法(重写)
  • ◆2.3、Spring启动类
  • ◆2.4、执行结果
  • ◆2.5、经典面试问题
  • ◆3总结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档