热门课程

免费试听

上课方式

开班时间

当前位置: 首页 -   文章 -   新闻动态 -   正文

Spring Bean生命周期(面试问题)

知了堂姐
2024-07-08 17:22:16
0

去一些企业面试时,经常会被问到Spring的问题,有一次就被问到关于Spring中Bean的生命周期是怎样的?其实这也是在业务中经常会遇到的问题,但容易遗忘,所以这次专门总结一下。

提示:可以借鉴Servlet的生命周期,实例化、初始init、接收请求service、销毁destroy。

Bean 的完整生命周期

对于普通的Java对象,当new的时候创建对象,当它没有任何引用的时候被垃圾回收机制回收。而由Spring IoC容器托管的对象,它们的生命周期完全由容器控制。Spring中每个Bean的生命周期如下:

如上图所示,Bean的生命周期还是比较复杂的,下面来对上图每一个步骤做文字描述:

Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化;

Bean实例化后对将Bean的引入和值注入到Bean的属性中;

如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法;

如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;

如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来;

如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的

postProcessBeforeInitialization()方法;

如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用;

如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的

postProcessAfterInitialization()方法;

此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁;

如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。

说实话,看了这么多面试题,只有这道面试题的答案内容是最多的,其实很多时候我们并不会真的去实现上面所描述的那些接口,如果在面试时被问到Spring Bean生命周期,我相信很多人说不出来,以下我分了三个阶段来深入了解下bean的生命周期,让小伙伴有更加深刻的理解!

生命周期的三个阶段

先补充下spring的作用域

目前Spring Bean的作用域或者说范围主要有五种。

第一创建阶段

Spring工厂何时创建对象

scope = “singleton”(默认)

```java
Spring工厂创建的同时,对象创建
ClassPathXmlApplicationContext s1 = new ClassPathXmlApplicationContext("application.xml");
注意:lazy-init="true" 这种情况下是在获取对象的时候才创建

```

scope = “prototype”

```java
Spring工厂在获取对象的时候创建对象.
ClassPathXmlApplicationContext s1 = new ClassPathXmlApplicationContext("application.xml");
Object student = s1.getBean("student");
```

第二初始化阶段

Spring工厂在创建完成对象后,调用对象的初始化方法,完成对应的初始化操作  
1. 初始化方法提供: 程序员根据需求,提供初始化方法,最终完成初始化操作  
2. 初始化方法调用: Spring工厂进行调用

InitializingBean接口

```java
实现接口 重写方法
@Override
public void afterPropertiesSet() throws Exception {
    //这里写初始化的内容.数据库?
    System.out.println("初始化方法");
}
```

自己提供一个普通方法 配置到 配置文件

```java
public void myInit(){
    System.out.println("我自己定义的初始化方法");
}

```

细节分析

1.既实现了 InitializingBean 又自己定义了 执行顺序?
```java
1. InitializingBean接口
2. 自定义的初始化
```
2.注入一定发生在初始化操作前面
```java
public class student implements InitializingBean {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        System.out.println("student的set方法");
        this.name = name;
    }
    public student() {
        System.out.println("学生类的无参构造");
    }
    @Override
    public String toString() {
        return "学生类";
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化方法");
    }
    public void myInit(){
        System.out.println("我自己定义的初始化方法");
    }
}
 
ClassPathXmlApplicationContext s1 = new ClassPathXmlApplicationContext("application.xml");
控制台输出:
学生类的无参构造
student的set方法
初始化方法
我自己定义的初始化方法
```
3.什么叫初始化操作
```
资源的初始化:网络 IO 数据库 ......
```

第三销毁阶段

DisposableBean接口

```java
//重写方法
@Override
public void destroy() throws Exception {
    System.out.println("销毁方法");
}
ClassPathXmlApplicationContext s1 = new ClassPathXmlApplicationContext("application.xml");
s1.close();//关闭工厂执行销毁方法
```

自定义方法

1. 不适用于scope="prototype"
2. 什么叫销毁操作
   ```
   主要是做一些资源的释放操作 io.close() connection.close();
   ```

总结:

Spring 容器可以管理 singleton 作用域下 bean 的生命周期,在此作用域下,Spring 能够精确地知道bean何时被创建,何时初始化完成,以及何时被销毁。而对于 prototype 作用域的bean,Spring只负责创建,当容器创建了 bean 的实例后,bean 的实例就交给了客户端的代码管理,Spring容器将不再跟踪其生命周期,并且不会管理那些被配置成prototype作用域的bean的生命周期。

大体的三个阶段

  • 实例化并属性赋值 Instantiation、Populate
  • 初始化 Initialization
  • 销毁 Destruction

回顾看下描述内容,结合代码再理解下,相信大家更加理解什么是Spring Bean的生命周期了吧!

记得点赞+关注哦~~

大家都在看

科技赋能教育,实力根本不允许知了堂低调

2024-07-08 浏览次数:0

Java代码如何对架构改进?

2024-07-08 浏览次数:0

春令营落幕,回顾关键事项,终于懂了选择知了堂的理...

2024-07-08 浏览次数:0

金九银十,应届生如何把握今年最后的机会?

2024-07-08 浏览次数:0

女生适合学前端还是后端?前端和后端介绍

2024-07-08 浏览次数:0

零基础学Java难吗?送你零基础学Java必备攻...

2024-07-08 浏览次数:0
最新资讯