问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

深入解析Spring Bean生命周期:从实例化到销毁的完整指南

创作时间:
作者:
@小白创作中心

深入解析Spring Bean生命周期:从实例化到销毁的完整指南

引用
CSDN
8
来源
1.
https://blog.csdn.net/dazhong2012/article/details/138170264
2.
https://blog.csdn.net/m0_68948067/article/details/139182295
3.
https://blog.csdn.net/FebruaryQ/article/details/138688014
4.
https://blog.csdn.net/m0_51176516/article/details/139265116
5.
https://developer.aliyun.com/article/601034
6.
https://my.oschina.net/emacs_8706270/blog/17058655
7.
https://www.cnblogs.com/DCFV/p/18355755
8.
https://www.cnblogs.com/dabuliu/p/18406441

在Spring框架中,Bean的生命周期管理是其核心功能之一。从创建到销毁,Spring容器会按照预定的流程对Bean进行管理,这个过程包含了多个关键阶段和扩展点。深入理解Bean的生命周期,有助于开发者更好地控制Bean的行为,充分利用Spring提供的强大功能进行灵活开发。

01

Bean生命周期的整体流程

如上图所示,Spring Bean的生命周期主要包含以下几个阶段:

  1. 实例化(Instantiation):Spring容器根据配置创建Bean的实例。
  2. 属性注入(Property Injection):通过依赖注入的方式,为Bean的属性赋值。
  3. 初始化(Initialization):在Bean的所有属性设置完成之后,执行初始化操作。
  4. 使用(Ready to Use):Bean初始化完成后,就可以被应用的其他部分使用。
  5. 销毁(Destruction):当容器关闭时,执行销毁操作,释放资源。
02

关键阶段详解

1. 实例化阶段

在实例化阶段,Spring容器会首先检查是否有实现了BeanFactoryPostProcessor接口的Bean。如果有,会在实例化其他Bean之前回调该接口的postProcessBeanFactory()方法,允许对Bean的配置元数据进行更改。

实例化是通过反射实现的。Spring会根据配置(XML、注解或JavaConfig)创建Bean的实例。

2. 属性注入阶段

属性注入阶段主要完成依赖注入工作。Spring容器会利用反射技术,根据配置将属性值及依赖Bean注入到当前Bean实例中。

3. 初始化阶段

初始化阶段是Bean生命周期中最为复杂的部分,包含了多个扩展点:

  • BeanNameAware、BeanFactoryAware、ApplicationContextAware:如果Bean实现了这些接口,Spring会相应地调用setBeanName()setBeanFactory()setApplicationContext()方法,传递相关信息。
  • BeanPostProcessor:Spring会调用所有注册的BeanPostProcessorpostProcessBeforeInitialization()方法,对Bean进行预初始化处理。
  • InitializingBean:如果Bean实现了InitializingBean接口,Spring会调用afterPropertiesSet()方法进行初始化。
  • 自定义init-method:可以通过XML配置或@Bean注解的initMethod属性指定初始化方法。
  • @PostConstruct:标注的方法会在依赖注入完成后被调用,用于执行初始化逻辑。
  • 再次调用BeanPostProcessorpostProcessAfterInitialization()方法,进行初始化后的处理。

4. 使用阶段

当Bean通过所有初始化步骤后,它就完全准备好了,可以被应用程序使用。此时,Bean会一直驻留在应用上下文中,直到上下文环境被销毁。

5. 销毁阶段

当Spring容器关闭时,会触发Bean的销毁过程:

  • DisposableBean:如果Bean实现了DisposableBean接口,Spring会调用destroy()方法。
  • 自定义destroy-method:可以通过XML配置或@Bean注解的destroyMethod属性指定销毁方法。
03

实战应用

下面通过一个简单的实战案例来演示Spring Bean的生命周期:

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class UserService implements InitializingBean, DisposableBean {
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    public void doSomething() {
        System.out.println("UserService is doing something: " + message);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("UserService is initializing...");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("UserService is destroying...");
    }
}

在Spring配置类中定义Bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class AppConfig {

    @Bean
    @Scope("prototype") // 设置作用域为prototype
    public UserService userService() {
        return new UserService();
    }
}

在主程序中,我们创建Spring应用上下文,获取UserService的Bean实例,并调用其方法:

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = context.getBean(UserService.class);
        userService.setMessage("Hello, Spring!");
        userService.doSomething();
        ((AnnotationConfigApplicationContext) context).close();
    }
}

当运行上述代码时,你会看到如下输出:

UserService is initializing...
UserService is doing something: Hello, Spring!
UserService is destroying...

这表明Bean的初始化和销毁方法都被正确调用。

04

最佳实践

  1. Bean的定义与配置

    • 可以使用XML、JavaConfig或注解方式定义Bean。推荐使用注解方式,因为它更简洁直观。
    • 使用@Component@Service@Repository@Controller等注解来标识不同类型的Bean,有助于Spring容器更好地理解Bean的用途。
  2. 作用域的选择

    • Singleton:默认作用域,适用于无状态的Bean。
    • Prototype:每次请求都创建新实例,适用于有状态的Bean。
    • RequestSession:仅在Web应用中使用,分别在每次HTTP请求和会话中创建新实例。
  3. 生命周期方法的使用

    • 尽量使用@PostConstruct@PreDestroy注解,而不是实现InitializingBeanDisposableBean接口,以保持代码的解耦性。
    • 如果需要更复杂的初始化逻辑,可以使用BeanPostProcessor

通过合理利用Spring Bean的生命周期,开发者可以更好地控制应用中对象的创建、初始化和销毁过程,从而构建出更加健壮和灵活的系统。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号